pdp10_elf36: return {Sh,Sym}Tab with s{h,t}_name:s already translated, do not return {Sh,}StrTab; nm: adjust

This commit is contained in:
Mikael Pettersson
2019-08-28 19:49:38 +02:00
parent cb450ce096
commit aa8791f897
3 changed files with 73 additions and 35 deletions

View File

@@ -478,6 +478,7 @@
-record(elf36_Shdr,
{ sh_name :: elf36_Word() % Section name, index in string tbl
| string() % Name (in-core only)
, sh_type :: elf36_Word() % Type of section
, sh_flags :: elf36_Word() % Miscellaneous section attributes
, sh_addr :: elf36_Addr() % Section virtual addr at execution
@@ -610,6 +611,7 @@
-record(elf36_Sym,
{ st_name :: elf36_Word() % Symbol name, index in string tbl
| string() % Name (in-core only)
, st_value :: elf36_Addr() % Value of the symbol
, st_size :: elf36_Word() % Associated symbol size
, st_info :: elf36_Uchar() % Type and binding attributes

View File

@@ -227,13 +227,13 @@ check_Ehdr_e_shentsize(Ehdr) ->
%% I/O of ShTab ================================================================
-spec read_ShTab(pdp10_stdio:file(), #elf36_Ehdr{})
-> {ok, {[#elf36_Shdr{}], term()}} | {error, {module(), term()}}.
-> {ok, [#elf36_Shdr{}]} | {error, {module(), term()}}.
read_ShTab(FP, Ehdr) ->
#elf36_Ehdr{ e_shoff = ShOff
, e_shnum = ShNum0
, e_shstrndx = ShStrNdx } = Ehdr,
case ShOff of
0 -> {ok, {[], []}};
0 -> {ok, []};
_ ->
case pdp10_stdio:fseek(FP, {bof, ShOff}) of
ok ->
@@ -243,9 +243,7 @@ read_ShTab(FP, Ehdr) ->
case read_ShTab(FP, ShNum - 1, [Shdr0]) of
{ok, ShTab} ->
case read_ShStrTab(FP, ShTab, ShStrNdx, Shdr0) of
{ok, ShStrTab} ->
%% TODO; now change the sh_names in ShTab to be strings
{ok, {ShTab, ShStrTab}};
{ok, ShStrTab} -> read_ShTab_names(ShTab, ShStrTab);
{error, _Reason} = Error -> Error
end;
{error, _Reason} = Error -> Error
@@ -266,6 +264,22 @@ read_ShTab(FP, ShNum, Shdrs) ->
{error, _Reason} = Error -> Error
end.
read_ShTab_names(ShTab, ShStrTab) ->
read_ShTab_names(ShTab, ShStrTab, []).
read_ShTab_names([], _ShStrTab, Acc) -> {ok, lists:reverse(Acc)};
read_ShTab_names([Shdr | ShTab], ShStrTab, Acc) ->
case read_Shdr_name(Shdr, ShStrTab) of
{ok, NewShdr} -> read_ShTab_names(ShTab, ShStrTab, [NewShdr | Acc]);
{error, _Reason} = Error -> Error
end.
read_Shdr_name(Shdr = #elf36_Shdr{sh_name = ShName}, ShStrTab) ->
case get_name(ShStrTab, ShName) of
{ok, Name} -> {ok, Shdr#elf36_Shdr{sh_name = Name}};
{error, _Reason} = Error -> Error
end.
%% I/O of ShStrTab =============================================================
read_ShStrTab(FP, ShTab, ShStrNdx, Shdr0) ->
@@ -300,11 +314,27 @@ read_StrTab(FP, ShTab, Index) ->
false -> {error, {?MODULE, {wrong_strtab_index, Index}}}
end.
%% reading a name from a StrTab ================================================
get_name(_StrTab, 0) -> {ok, ""}; % TODO: or some marker for "absent"
get_name(StrTab, Index) ->
try lists:nthtail(Index, StrTab) of
[C | Tail] -> get_name(C, Tail, [])
catch _C:_R ->
{error, {?MODULE, {wrong_index_in_strtab, Index}}}
end.
get_name(0, _Tail, Acc) -> {ok, lists:reverse(Acc)};
get_name(C1, [C2 | Tail], Acc) -> get_name(C2, Tail, [C1 | Acc]);
get_name(_C, [], _Acc) -> {error, {?MODULE, strtab_not_nul_terminated}}.
%% I/O of SymTab ===============================================================
-spec read_SymTab(pdp10_stdio:file(), [#elf36_Shdr{}])
-> {ok, [#elf36_Sym{}]} | {error, {module(), term()}}.
read_SymTab(FP, ShTab) ->
case find_SymTab(ShTab) of
false -> {ok, {[], []}};
false -> {ok, []};
{ok, Shdr} ->
#elf36_Shdr{ sh_link = ShLink
, sh_entsize = ShEntSize
@@ -320,12 +350,12 @@ read_SymTab(FP, ShTab) ->
{ok, StrTab} ->
SymNum = ShSize div ?ELF36_SYM_SIZEOF,
case SymNum of
0 -> {ok, {[], StrTab}};
0 -> {ok, []};
_ ->
case pdp10_stdio:fseek(FP, {bof, ShOffset}) of
ok ->
case read_SymTab(FP, SymNum, []) of
{ok, SymTab} -> {ok, {SymTab, StrTab}};
{ok, SymTab} -> read_SymTab_names(SymTab, StrTab);
{error, _Reason} = Error -> Error
end;
{error, _Reason} = Error -> Error
@@ -347,6 +377,22 @@ find_SymTab([]) -> false;
find_SymTab([#elf36_Shdr{sh_type = ?SHT_SYMTAB} = Shdr | _]) -> {ok, Shdr};
find_SymTab([_Shdr | ShTab]) -> find_SymTab(ShTab).
read_SymTab_names(SymTab, StrTab) ->
read_SymTab_names(SymTab, StrTab, []).
read_SymTab_names([], _StrTab, Acc) -> {ok, lists:reverse(Acc)};
read_SymTab_names([Sym | SymTab], StrTab, Acc) ->
case read_Sym_name(Sym, StrTab) of
{ok, NewSym} -> read_SymTab_names(SymTab, StrTab, [NewSym | Acc]);
{error, _Reason} = Error -> Error
end.
read_Sym_name(Sym = #elf36_Sym{st_name = StName}, StrTab) ->
case get_name(StrTab, StName) of
{ok, Name} -> {ok, Sym#elf36_Sym{st_name = Name}};
{error, _Reason} = Error -> Error
end.
%% I/O of #elf36_Shdr{} ========================================================
read_Shdr(FP) -> read_record(FP, elf36_Shdr_desc()).
@@ -456,6 +502,10 @@ format_error(Reason) ->
io_lib:format("wrong sh_size ~p in symtab section header", [ShSize]);
eof ->
"premature EOF";
{wrong_index_in_strtab, Index} ->
io_lib:format("out of range index ~p in string table", [Index]);
strtab_not_nul_terminated ->
"string table not NUL-terminated";
_ ->
io_lib:format("~p", [Reason])
end.

View File

@@ -165,9 +165,9 @@ nm1(Opts, PrintFile, File) ->
nm1(Opts, PrintFile, File, FP) ->
Ehdr = read_ehdr(File, FP),
{ShTab, _ShStrTab} = read_shtab(File, FP, Ehdr),
{SymTab, StrTab} = read_symtab(File, FP, ShTab),
print_symtab(Opts, PrintFile, File, ShTab, SymTab, StrTab).
ShTab = read_shtab(File, FP, Ehdr),
SymTab = read_symtab(File, FP, ShTab),
print_symtab(Opts, PrintFile, File, ShTab, SymTab).
read_ehdr(File, FP) ->
case pdp10_elf36:read_Ehdr(FP) of
@@ -180,7 +180,7 @@ read_ehdr(File, FP) ->
read_shtab(File, FP, Ehdr) ->
case pdp10_elf36:read_ShTab(FP, Ehdr) of
{ok, {ShTab, ShStrTab}} -> {ShTab, ShStrTab};
{ok, ShTab} -> ShTab;
{error, Reason} ->
escript_runtime:fatal("failed to read section header table in ~s: ~s\n",
[File, error:format(Reason)])
@@ -188,22 +188,22 @@ read_shtab(File, FP, Ehdr) ->
read_symtab(File, FP, ShTab) ->
case pdp10_elf36:read_SymTab(FP, ShTab) of
{ok, {SymTab, StrTab}} -> {SymTab, StrTab};
{ok, SymTab} -> SymTab;
{error, Reason} ->
escript_runtime:fatal("failed to read symbol table table in ~s: ~s\n",
[File, error:format(Reason)])
end.
print_symtab(Opts, PrintFile, File, ShTab, SymTab, StrTab) ->
print_symtab(Opts, PrintFile, File, ShTab, SymTab) ->
case PrintFile of
true -> io:format("\n~s:\n", [File]);
false -> ok
end,
[sym_print(Opts, File, ShTab, Sym)
|| Sym <- syms_sort(Opts, syms_assemble(ShTab, SymTab, StrTab))],
|| Sym <- syms_sort(Opts, syms_assemble(ShTab, SymTab))],
ok.
sym_print(Opts, File, ShTab, {Sym, Value, Name}) ->
sym_print(Opts, File, ShTab, {Sym = #elf36_Sym{st_name = Name}, Value}) ->
case sym_type_letter(ShTab, Sym) of
0 -> ok; % ignored
Type ->
@@ -309,30 +309,16 @@ syms_cmpfn(Opts) ->
end
end.
sym_cmp_value({_, Val1, _}, {_, Val2, _}) -> Val1 =< Val2.
sym_cmp_value({_, Val1}, {_, Val2}) -> Val1 =< Val2.
sym_cmp_name({_, _, Name1}, {_, _, Name2}) -> Name1 =< Name2.
sym_cmp_name({Sym1, _}, {Sym2, _}) ->
Sym1#elf36_Sym.st_name =< Sym2#elf36_Sym.st_name.
syms_assemble(ShTab, SymTab, StrTab) ->
syms_assemble(ShTab, SymTab) ->
lists:map(fun(Sym) ->
{Sym, sym_value(ShTab, Sym), sym_name(StrTab, Sym)}
{Sym, sym_value(ShTab, Sym)}
end, SymTab).
sym_name(StrTab, #elf36_Sym{st_name = Index}) ->
{ok, Name} = get_name(StrTab, Index),
Name.
get_name(StrTab, Index) ->
try lists:nthtail(Index, StrTab) of
[_|_] = Tail -> get_name2(Tail, [])
catch _C:_R ->
{error, {bad_strtab_index, Index}}
end.
get_name2([], _Acc) -> {error, strtab_not_nul_terminated};
get_name2([0 | _Tail], Acc) -> {ok, lists:reverse(Acc)};
get_name2([Ch | Tail], Acc) -> get_name2(Tail, [Ch | Acc]).
sym_value(ShTab, #elf36_Sym{st_shndx = ShNdx, st_value = Value}) ->
ShNum = length(ShTab),
Base =