0

while I'm trying to run this project https://github.com/taviso/loadlibrary/ which is mainly for running windows defender under Linux

I run into an issue in the genmapsym.sh which suppose to generate symbols from a .map file.

The genmapsym.sh contain the following code :

awk 'BEGIN { printf ".macro symbol name, address\n.set \\name, \\address\n.func \\name\n.endfunc\n.endm\n" }

    /Publics by Value/,/Program entry point/ {

        if (gsub(/^ ....:/,"'${1}'+0x")) {
            gsub(/[\"/^}{\[\]$?:@()><`\'\''|~,=!+&*-]/, "_",$2);
            printf "symbol %s,%s\n",$2,$1
        }
}' | as -o ${2} -gstabs+ --32

whenever I try to run it to get the symbols right in gdb I get this error

gdb> shell bash genmapsym.sh 0x5a100000+0x1000 symbols_3383.o < engine/mpengine.map
awk: line 6: regular expression compile failed (bad class -- [], [^] or [)
[\"
awk: line 6: missing ) near }
awk: 6: unexpected character '\'
awk: line 6: syntax error at or near [
awk: line 6: extra ')'

in the project repo there is this note which I couldn't make sense of it :

Note that genmapsym.sh assumes you're using GNU awk.

because I don't have any idea what I'm using in bash by default, or at least know how to figure out which is the default.

My environment is :

Linux ubuntu 5.4.0-65-generic #73~18.04.1-Ubuntu SMP 2021 x86_64 x86_64 x86_64 GNU/Linux
awk version: mawk 1.3.3 

how could I fix this so that it will run correctly in my env.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
alex
  • 19
  • 4
  • What is output after you do `awk --version`? – Daweo Feb 15 '21 at 10:34
  • that command is not supported by awk, but I used `awk -W version` which is `mawk 1.3.3 `@Daweo – alex Feb 15 '21 at 10:37
  • Well, there you go then. You're using GNU awk specific code with a different awk. – Shawn Feb 15 '21 at 10:42
  • 1
    That code isn't using any gawk-specific features, instead it's relying on gawk being more tolerant of its bugs than other awks. YMMV with that - you'd be better off just fixing the bugs so it'll work in any awk, including future versions of gawk that might decide not to be as tolerant. – Ed Morton Feb 15 '21 at 15:29

2 Answers2

0

Your main problem is this regexp used in gsub():

/[\"/^}{\[\]$?:@()><`\'\''|~,=!+&*-]/

Issue 1: See that \'\''? I assume that was intended to be '\'' or \\'\''.

Your awk script is delimited by 's: awk 'BEGIN ... }' | .... In shell you cannot have a ' inside a '-delimted string, including in scripts. One workaround is to use '\'' inside the string as the first ' provides an end-of-string delimiter, the \' provides a ' outside of the string, then the final ' provides a new start-of-string delimiter.

So you can't write either of these to get a ' between foo and bar"

'foo'bar'
'foo\'bar'

but you CAN write:

'foo'\''bar'

In awk you can alternatively use the ASCII octal code for ':

'foo\047bar'

which has the advantage that it'll work whether the script is stored in a file or used on the command line.

Issue 2: See that \]? That is not POSIX-compliant and so YMMV with what any version of any awk will do with it. To get a ] inside a bracket expression it has to be the first non-^ character in the bracket expression. So for portability to all awks don't write [x\]y], write []xy] instead.

Issue 3: Aside from the regexp in that gsub(), you have an issue in the replacement text of your other gsub(): "'${1}'+0x". That is NOT how you pass the value of a shell variable to an awk script as it makes the shell variable expand to become part of the script and leaves it's value open to interpretation by the shell so leads to all kinds of potential cryptic errors and security issues. Pass the value of the shell variable to awk as an awk variable instead - see how-do-i-use-shell-variables-in-an-awk-script.

So, instead of:

awk 'BEGIN { printf ".macro symbol name, address\n.set \\name, \\address\n.func \\name\n.endfunc\n.endm\n" }

    /Publics by Value/,/Program entry point/ {

        if (gsub(/^ ....:/,"'${1}'+0x")) {
            gsub(/[\"/^}{\[\]$?:@()><`\'\''|~,=!+&*-]/, "_",$2);
            printf "symbol %s,%s\n",$2,$1
        }
}'

you should with minimal changes to get it functional be using this instead:

awk -v num="$1" 'BEGIN { printf ".macro symbol name, address\n.set \\name, \\address\n.func \\name\n.endfunc\n.endm\n" }

    /Publics by Value/,/Program entry point/ {

        if (gsub(/^ ....:/,num"+0x")) {
            gsub(/[]["/^}{$?:@()><`'\''|~,=!+&*-]/, "_",$2);
            printf "symbol %s,%s\n",$2,$1
        }
}'

I also removed some of the unnecessary escapes from within the bracket expression (e.g. you don't need \", just ", and that would also produce warning or error messages depending on your awk version).

Range expressions (/Publics by Value/,/Program entry point/) are usually a bad idea btw - I'd use a flag instead, see is-a-start-end-range-expression-ever-useful-in-awk.

Ed Morton
  • 188,023
  • 17
  • 78
  • 185
  • @rowboat I doubt it but if you have that then please try it and let us know. – Ed Morton Feb 17 '21 at 13:28
  • Good to know. It doesn't even raise a warning with gawk `--traditional` or `--lint` or `--posix` so I'm guessing that's not POSIX conformant. – Ed Morton Feb 17 '21 at 14:47
-1

used awk -W version which is mawk 1.3.3

This is not compliant with requirement

you're using GNU awk

AWK does have various implementations, project you attempt to run require GNU AWK (also known as gawk) whilst you provide it Michael Brennan's implementation (mawk).

Daweo
  • 31,313
  • 3
  • 12
  • 25
  • any idea how to fix that as I'm using the last version of ubuntu that is available for download. – alex Feb 15 '21 at 10:44
  • after downloading gawk any other instruction to make it the default in bash? – alex Feb 15 '21 at 10:46
  • @alex I am not versed with bash or ubuntu, so I might only suggest that you read about `PATH` variable. – Daweo Feb 15 '21 at 10:52
  • @alex: make sure the `gawk` package is installed, and use `gawk` explicitly. Or on Debian/Ubuntu systems, you can use `sudo update-alternative awk` to set which awk is `/usr/bin/awk`. – Peter Cordes Feb 15 '21 at 11:15