Bug 256909

Summary: libucl upgrade in a0409676120c1e558d0ade943019934e0f15118d breaks ABI
Product: Base System Reporter: Michael Osipov <michael.osipov>
Component: binAssignee: Baptiste Daroussin <bapt>
Status: New ---    
Severity: Affects Some People CC: bapt, michael.osipov
Priority: ---    
Version: 12.2-STABLE   
Hardware: Any   
OS: Any   

Description Michael Osipov 2021-06-30 16:53:50 UTC
* I have installed a new FreeBSD host from 12.2-RELEASE image
* Installed gitup(1):
# fetch -o gitup.zip https://codeload.github.com/johnmehr/gitup/zip/main
# unzip gitup.zip
# cd gitup-main
# mkdir -p /usr/local/etc /usr/local/sbin /usr/local/man/man1 /usr/local/man/man5
# make
# make MK_DEBUG_FILES=no DESTDIR=/usr/local BINDIR=/sbin MANDIR=/man/man install
# cd ..
# rm -rf gitup*

gitup makes use of ucl_iterate_object().

gitup works, it is now used to fetch a shallow copy of stable/12 to update base from release to stable. After stable has been applied and the system has been rebooted gitup fails with undefined symbol "ucl_iterate_object". One needs to recompile gitup to make it work again with stable/12.

The reason is commit a0409676120c1e558d0ade943019934e0f15118d (libucl: vendor import snapshort 20210314). In this specific commit the following has been performed:
...
> -UCL_EXTERN const ucl_object_t* ucl_object_iterate (const ucl_object_t *obj,
> -		ucl_object_iter_t *iter, bool expand_values);
> +UCL_EXTERN const ucl_object_t* ucl_object_iterate_with_error (const ucl_object_t *obj,
> +		ucl_object_iter_t *iter, bool expand_values, int *ep);
> +
>  #define ucl_iterate_object ucl_object_iterate
> +#define ucl_object_iterate(ob, it, ev) ucl_object_iterate_with_error((ob), (it), (ev), NULL)
...
> -ucl_object_iterate (const ucl_object_t *obj, ucl_object_iter_t *iter, bool expand_values)
> +ucl_object_iterate_with_error (const ucl_object_t *obj, ucl_object_iter_t *iter, bool expand_values,
> +    int *ep)

The dynamic symbol table has been modified and the symbol ucl_object_iterate is gone after base has been updated. This is a breaking change for me which I don't expect. While I can recompile gitup, no issue, others will have problems with other ports which may rely on this symbol to exist. This also means that one cannot build this port in 12.2-RELEASE jail and use it in a 12-STABLE system.

The vendor change must be modified that no macro is used, but the old symbol is retained and the replaced function simply calls the new one.
Comment 1 Michael Osipov 2021-06-30 17:22:22 UTC
On 12.2-RELEASE:

> root@hotzenplotz:~/gitup-main # uname -a
> FreeBSD hotzenplotz.ad001.siemens.net 12.2-RELEASE FreeBSD 12.2-RELEASE r366954 GENERIC  amd64
> # readelf -a /usr/local/sbin/gitup | grep ucl_object_iterate
> 0000002129d0 005700000007 R_X86_64_JUMP_SLOT  0000000000000000 ucl_object_iterate + 0
>     87: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND ucl_object_iterate
> # readelf -a /usr/lib/libprivateucl.so | grep ucl_object_iterate
> 000000023638 003b00000007 R_X86_64_JUMP_SLOT  000000000000f100 ucl_object_iterate + 0
> 0000000237d8 005300000007 R_X86_64_JUMP_SLOT  0000000000011100 ucl_object_iterate_full + 0
>     59: 000000000000f100   134 FUNC    GLOBAL DEFAULT   12 ucl_object_iterate
>     83: 0000000000011100   343 FUNC    GLOBAL DEFAULT   12 ucl_object_iterate_full
>    105: 0000000000011260   112 FUNC    GLOBAL DEFAULT   12 ucl_object_iterate_free
>    130: 00000000000110f0    13 FUNC    GLOBAL DEFAULT   12 ucl_object_iterate_safe
>    161: 0000000000011070   122 FUNC    GLOBAL DEFAULT   12 ucl_object_iterate_reset
>    166: 0000000000011030    49 FUNC    GLOBAL DEFAULT   12 ucl_object_iterate_new

On 12-STABLE:
> root@deblndw013x:~
> # uname -a
> FreeBSD deblndw013x.ad001.siemens.net 12.2-STABLE FreeBSD 12.2-STABLE GENERIC  amd64
> root@deblndw013x:~
> # readelf -a /usr/local/sbin/gitup | grep ucl_object_iterate
> 000000211b28 005500000007 R_X86_64_JUMP_SLOT  0000000000000000 ucl_object_iterate_with_error + 0
>     85: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND ucl_object_iterate_with_error
> root@deblndw013x:~
> #  readelf -a /usr/lib/libprivateucl.so | grep ucl_object_iterate
> 000000026338 00b400000007 R_X86_64_JUMP_SLOT  0000000000010260 ucl_object_iterate_with_error + 0
> 000000026418 005b00000007 R_X86_64_JUMP_SLOT  0000000000012800 ucl_object_iterate_new + 0
> 000000026420 00e200000007 R_X86_64_JUMP_SLOT  0000000000012930 ucl_object_iterate_safe + 0
> 000000026428 004100000007 R_X86_64_JUMP_SLOT  0000000000012ab0 ucl_object_iterate_free + 0
> 0000000264e8 009500000007 R_X86_64_JUMP_SLOT  0000000000012940 ucl_object_iterate_full + 0
>     65: 0000000000012ab0   118 FUNC    GLOBAL DEFAULT   12 ucl_object_iterate_free
>     91: 0000000000012800    50 FUNC    GLOBAL DEFAULT   12 ucl_object_iterate_new
>    149: 0000000000012940   366 FUNC    GLOBAL DEFAULT   12 ucl_object_iterate_full
>    180: 0000000000010260   134 FUNC    GLOBAL DEFAULT   12 ucl_object_iterate_with_error
>    205: 00000000000128a0   135 FUNC    GLOBAL DEFAULT   12 ucl_object_iterate_reset
>    226: 0000000000012930    13 FUNC    GLOBAL DEFAULT   12 ucl_object_iterate_safe
Comment 2 Mark Linimon freebsd_committer freebsd_triage 2021-07-01 04:16:15 UTC
^Triage: over to committer of contrib/libucl/src/ucl_msgpack.c .
Comment 3 Michael Osipov 2021-07-01 11:14:20 UTC
Host in question updated:

# uname -a
FreeBSD hotzenplotz.ad001.siemens.net 12.2-STABLE FreeBSD 12.2-STABLE GENERIC  amd64
# gitup ports
ld-elf.so.1: /usr/local/sbin/gitup: Undefined symbol "ucl_object_iterate"