glibc: clang 12 assembler regression workaround

Our glibc stub assembly file looked something like this:

```
.globl _Exit_2_2_5
.type _Exit_2_2_5, %function;
.symver _Exit_2_2_5, _Exit@@GLIBC_2.2.5
.hidden _Exit_2_2_5
_Exit_2_2_5:
```

With clang 12, the shared objects this produced stopped having any
exported symbols. When I removed the `.hidden` directive, it resolved
the issue, however, there are now unwanted exports:

```
$ readelf -W --dyn-syms libc.so.6 | grep sys_errlist
   139: 000000000001ee08     0 FUNC    GLOBAL DEFAULT    7 _sys_errlist_GLIBC_2_3
   147: 000000000001ee08     0 FUNC    GLOBAL DEFAULT    7 _sys_errlist_GLIBC_2_4
   395: 000000000001ee08     0 FUNC    GLOBAL DEFAULT    7 _sys_errlist_GLIBC_2_2_5
   487: 000000000001ee08     0 FUNC    GLOBAL DEFAULT    7 sys_errlist_GLIBC_2_2_5
  1266: 000000000001ee08     0 FUNC    GLOBAL DEFAULT    7 _sys_errlist@@GLIBC_2.12
  1267: 000000000001ee08     0 FUNC    GLOBAL DEFAULT    7 _sys_errlist@GLIBC_2.2.5
  1268: 000000000001ee08     0 FUNC    GLOBAL DEFAULT    7 _sys_errlist@GLIBC_2.3
  1269: 000000000001ee08     0 FUNC    GLOBAL DEFAULT    7 _sys_errlist@GLIBC_2.4
  2137: 000000000001ee08     0 FUNC    GLOBAL DEFAULT    7 sys_errlist@@GLIBC_2.12
  2138: 000000000001ee08     0 FUNC    GLOBAL DEFAULT    7 sys_errlist@GLIBC_2.2.5
  2139: 000000000001ee08     0 FUNC    GLOBAL DEFAULT    7 sys_errlist@GLIBC_2.3
  2140: 000000000001ee08     0 FUNC    GLOBAL DEFAULT    7 sys_errlist@GLIBC_2.4
  2156: 000000000001ee08     0 FUNC    GLOBAL DEFAULT    7 sys_errlist_GLIBC_2_3
  2161: 000000000001ee08     0 FUNC    GLOBAL DEFAULT    7 sys_errlist_GLIBC_2_4
```

Every line here without an `@` symbol is an unwanted export. Before, the
unwanted ones had LOCAL HIDDEN linkage.

As a mitigation, I did two things:

 * Added `_GLIBC_` to the unwanted exports so that they would not
   conflict with anything.
 * Made the default export (the `@@` one) the bare symbol name. This
   appears to reduce the unwanted exports to only symbols that have more
   than one symbol (which is still quite many).

This will unblock progress on this branch, however, there is now a new
issue to solve, that the provided glibc stub .so files have too many
symbols exported. We will have to find a way to avoid this.
This commit is contained in:
Andrew Kelley 2021-02-28 00:53:05 -07:00
parent ab36a162d0
commit 4b1fe8e492

View File

@ -807,26 +807,26 @@ pub fn buildSharedObjects(comp: *Compilation) !void {
// .globl _Exit_2_2_5
// .type _Exit_2_2_5, %function;
// .symver _Exit_2_2_5, _Exit@@GLIBC_2.2.5
// .hidden _Exit_2_2_5
// _Exit_2_2_5:
const ver_index = ver_list.versions[ver_i];
const ver = metadata.all_versions[ver_index];
const sym_name = libc_fn.name;
// Default symbol version definition vs normal symbol version definition
const want_two_ats = chosen_def_ver_index != 255 and ver_index == chosen_def_ver_index;
const at_sign_str = "@@"[0 .. @boolToInt(want_two_ats) + @as(usize, 1)];
const want_default = chosen_def_ver_index != 255 and ver_index == chosen_def_ver_index;
const at_sign_str: []const u8 = if (want_default) "@@" else "@";
if (ver.patch == 0) {
const sym_plus_ver = try std.fmt.allocPrint(
arena,
"{s}_{d}_{d}",
.{ sym_name, ver.major, ver.minor },
);
const sym_plus_ver = if (want_default)
sym_name
else
try std.fmt.allocPrint(
arena,
"{s}_GLIBC_{d}_{d}",
.{ sym_name, ver.major, ver.minor },
);
try zig_body.writer().print(
\\.globl {s}
\\.type {s}, %function;
\\.symver {s}, {s}{s}GLIBC_{d}.{d}
\\.hidden {s}
\\{s}:
\\
, .{
@ -838,19 +838,20 @@ pub fn buildSharedObjects(comp: *Compilation) !void {
ver.major,
ver.minor,
sym_plus_ver,
sym_plus_ver,
});
} else {
const sym_plus_ver = try std.fmt.allocPrint(
arena,
"{s}_{d}_{d}_{d}",
.{ sym_name, ver.major, ver.minor, ver.patch },
);
const sym_plus_ver = if (want_default)
sym_name
else
try std.fmt.allocPrint(
arena,
"{s}_GLIBC_{d}_{d}_{d}",
.{ sym_name, ver.major, ver.minor, ver.patch },
);
try zig_body.writer().print(
\\.globl {s}
\\.type {s}, %function;
\\.symver {s}, {s}{s}GLIBC_{d}.{d}.{d}
\\.hidden {s}
\\{s}:
\\
, .{
@ -863,7 +864,6 @@ pub fn buildSharedObjects(comp: *Compilation) !void {
ver.minor,
ver.patch,
sym_plus_ver,
sym_plus_ver,
});
}
}