mirror of
https://github.com/mikpe/pdp10-tools.git
synced 2026-01-25 19:57:09 +00:00
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:
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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 =
|
||||
|
||||
Reference in New Issue
Block a user