[01/13] scripts/versions.awk: Add strings and hashes to <first-versions.h>

Message ID 3231520c8ff708bf771984715a02fd767f1c501e.1620323953.git.fweimer@redhat.com
State New
Headers show
Series
  • Linux: Move most stack management out of libpthread
Related show

Commit Message

Noah Goldstein via Libc-alpha May 6, 2021, 6:08 p.m.
This generates new macros of this from:

#define FIRST_VERSION_libc___pthread_mutex_lock_STRING "GLIBC_2.2.5"
#define FIRST_VERSION_libc___pthread_mutex_lock_HASH 0x9691a75

They are useful for symbol lookups using _dl_lookup_direct.
---
 scripts/versions.awk | 36 ++++++++++++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)

-- 
2.30.2

Comments

Noah Goldstein via Libc-alpha May 9, 2021, 9:42 p.m. | #1
On 5/6/21 2:08 PM, Florian Weimer via Libc-alpha wrote:
> This generates new macros of this from:

> 

> #define FIRST_VERSION_libc___pthread_mutex_lock_STRING "GLIBC_2.2.5"

> #define FIRST_VERSION_libc___pthread_mutex_lock_HASH 0x9691a75

> 

> They are useful for symbol lookups using _dl_lookup_direct.


Straight forward, makes sense, used in the next patch.

Tested on x86_64 and i686 without regression.

Tested-by: Carlos O'Donell <carlos@redhat.com>

Reviewed-by: Carlos O'Donell <carlos@redhat.com>


> ---

>  scripts/versions.awk | 36 ++++++++++++++++++++++++++++++++++++

>  1 file changed, 36 insertions(+)

> 

> diff --git a/scripts/versions.awk b/scripts/versions.awk

> index d56f4e712c..3291123666 100644

> --- a/scripts/versions.awk

> +++ b/scripts/versions.awk

> @@ -32,6 +32,29 @@ BEGIN {

>    sort = "sort -t. -k 1,1 -k 2n,2n -k 3 > " tmpfile;

>  }

>  

> +# GNU awk does not implement the ord and chr functions.

> +# <https://www.gnu.org/software/gawk/manual/html_node/Ordinal-Functions.html>

> +# says that they are "written very nicely", using code similar to what

> +# is included here.

> +function chr(c) {

> +    return sprintf("%c", c)

> +}

> +

> +BEGIN {

> +    for (c = 1; c < 127; c++) {

> +	ord_table[chr(c)] = c;

> +    }

> +}

> +

> +function ord(c) {

> +    if (ord_table[c]) {

> +	return ord_table[c];

> +    } else {

> +	printf("Invalid character reference: '%c'\n", c) > "/dev/stderr";

> +	++lossage;

> +    }

> +}

> +

>  # Remove comment lines.

>  /^ *#/ {

>    next;

> @@ -90,6 +113,17 @@ function close_and_move(name, real_name) {

>    system(move_if_change " " name " " real_name " >&2");

>  }

>  

> +# ELF hash, for use with symbol versions.

> +function elf_hash(s, i, acc) {

> +  acc = 0;

> +  for (i = 1; i <= length(s); ++i) {

> +      acc = and(lshift(acc, 4) + ord(substr(s, i, 1)), 0xffffffff);

> +      top = and(acc, 0xf0000000);

> +      acc = and(xor(acc, rshift(top, 24)), compl(top));

> +  }

> +  return acc;

> +}

> +

>  # Now print the accumulated information.

>  END {

>    close(sort);

> @@ -145,6 +179,8 @@ END {

>  	  && oldver ~ "^GLIBC_[0-9]" \

>  	  && sym ~ "^[A-Za-z0-9_]*$") {

>  	ver_val = oldver;

> +	printf("#define %s_STRING \"%s\"\n", first_ver_macro, ver_val) > first_ver_header;

> +	printf("#define %s_HASH 0x%x\n", first_ver_macro, elf_hash(ver_val)) > first_ver_header;

>  	gsub("\\.", "_", ver_val);

>  	printf("#define %s %s\n", first_ver_macro, ver_val) > first_ver_header;

>  	first_ver_seen[first_ver_macro] = 1;

> 



-- 
Cheers,
Carlos.

Patch

diff --git a/scripts/versions.awk b/scripts/versions.awk
index d56f4e712c..3291123666 100644
--- a/scripts/versions.awk
+++ b/scripts/versions.awk
@@ -32,6 +32,29 @@  BEGIN {
   sort = "sort -t. -k 1,1 -k 2n,2n -k 3 > " tmpfile;
 }
 
+# GNU awk does not implement the ord and chr functions.
+# <https://www.gnu.org/software/gawk/manual/html_node/Ordinal-Functions.html>
+# says that they are "written very nicely", using code similar to what
+# is included here.
+function chr(c) {
+    return sprintf("%c", c)
+}
+
+BEGIN {
+    for (c = 1; c < 127; c++) {
+	ord_table[chr(c)] = c;
+    }
+}
+
+function ord(c) {
+    if (ord_table[c]) {
+	return ord_table[c];
+    } else {
+	printf("Invalid character reference: '%c'\n", c) > "/dev/stderr";
+	++lossage;
+    }
+}
+
 # Remove comment lines.
 /^ *#/ {
   next;
@@ -90,6 +113,17 @@  function close_and_move(name, real_name) {
   system(move_if_change " " name " " real_name " >&2");
 }
 
+# ELF hash, for use with symbol versions.
+function elf_hash(s, i, acc) {
+  acc = 0;
+  for (i = 1; i <= length(s); ++i) {
+      acc = and(lshift(acc, 4) + ord(substr(s, i, 1)), 0xffffffff);
+      top = and(acc, 0xf0000000);
+      acc = and(xor(acc, rshift(top, 24)), compl(top));
+  }
+  return acc;
+}
+
 # Now print the accumulated information.
 END {
   close(sort);
@@ -145,6 +179,8 @@  END {
 	  && oldver ~ "^GLIBC_[0-9]" \
 	  && sym ~ "^[A-Za-z0-9_]*$") {
 	ver_val = oldver;
+	printf("#define %s_STRING \"%s\"\n", first_ver_macro, ver_val) > first_ver_header;
+	printf("#define %s_HASH 0x%x\n", first_ver_macro, elf_hash(ver_val)) > first_ver_header;
 	gsub("\\.", "_", ver_val);
 	printf("#define %s %s\n", first_ver_macro, ver_val) > first_ver_header;
 	first_ver_seen[first_ver_macro] = 1;