mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-11 19:25:58 +02:00
[PATCH 024/188] update symbol flags
From 4e1c01a42dc4ec155efd5ad6ff8bb6a49962948b Mon Sep 17 00:00:00 2001 From: Dmitry Boyarintsev <skalogryz.lists@gmail.com> Date: Fri, 27 Sep 2019 16:44:35 -0400 git-svn-id: branches/wasm@46020 -
This commit is contained in:
parent
1a80e89ccf
commit
52c059f027
@ -14,6 +14,7 @@ uses
|
|||||||
const
|
const
|
||||||
ACT_EXPORTRENAME = 'exportrename';
|
ACT_EXPORTRENAME = 'exportrename';
|
||||||
ACT_SYMBOLFLAG = 'symbolflag';
|
ACT_SYMBOLFLAG = 'symbolflag';
|
||||||
|
ACT_SYMBOLAUTO = 'symbolauto';
|
||||||
|
|
||||||
VERSION = '1.0';
|
VERSION = '1.0';
|
||||||
|
|
||||||
@ -25,7 +26,8 @@ begin
|
|||||||
writeln;
|
writeln;
|
||||||
writeln('options:');
|
writeln('options:');
|
||||||
writeln(' --exportrename @inputfile - renaming export names');
|
writeln(' --exportrename @inputfile - renaming export names');
|
||||||
writeln(' --symbolflag @inputfile - update symbol use flags');
|
writeln(' --symbolflag @inputfile - update symbol flags as specified in input');
|
||||||
|
writeln(' --symbolauto - update symbol by the use');
|
||||||
writeln(' --verbose - enabling verbose mode');
|
writeln(' --verbose - enabling verbose mode');
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -64,6 +66,8 @@ begin
|
|||||||
ExportRename(inputFn, ta.paramsFn, doVerbose);
|
ExportRename(inputFn, ta.paramsFn, doVerbose);
|
||||||
end else if ta.action = ACT_SYMBOLFLAG then begin
|
end else if ta.action = ACT_SYMBOLFLAG then begin
|
||||||
ChangeSymbolFlag(inputFn, ta.paramsFn);
|
ChangeSymbolFlag(inputFn, ta.paramsFn);
|
||||||
|
end else if ta.action = ACT_SYMBOLAUTO then begin
|
||||||
|
PredictSymbolsFromLink(inputFn, doVerbose);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -95,6 +99,8 @@ begin
|
|||||||
ls := Copy(ls, 3, length(ls)-2);
|
ls := Copy(ls, 3, length(ls)-2);
|
||||||
if (ls = 'verbose') then
|
if (ls = 'verbose') then
|
||||||
verbose := true
|
verbose := true
|
||||||
|
else if (ls = ACT_SYMBOLAUTO) then
|
||||||
|
acts.Add( TToolActions.Create(ls, ''))
|
||||||
else begin
|
else begin
|
||||||
if i<=ParamCount then begin
|
if i<=ParamCount then begin
|
||||||
fn:=ParamStr(i);
|
fn:=ParamStr(i);
|
||||||
|
@ -9,6 +9,7 @@ uses
|
|||||||
|
|
||||||
function ChangeSymbolFlagStream(st: TStream; syms: TStrings): Boolean;
|
function ChangeSymbolFlagStream(st: TStream; syms: TStrings): Boolean;
|
||||||
procedure ChangeSymbolFlag(const fn, symfn: string);
|
procedure ChangeSymbolFlag(const fn, symfn: string);
|
||||||
|
function PredictSymbolsFromLink(const wasmfn: string; doVerbose: Boolean = false): Boolean;
|
||||||
|
|
||||||
procedure MatchExportNameToSymName(const x: TExportSection; const l: TLinkingSection; dst: TStrings);
|
procedure MatchExportNameToSymName(const x: TExportSection; const l: TLinkingSection; dst: TStrings);
|
||||||
function ExportRenameSym(var x: TExportSection; syms: TStrings): Integer;
|
function ExportRenameSym(var x: TExportSection; syms: TStrings): Integer;
|
||||||
@ -63,41 +64,141 @@ end;
|
|||||||
// if a function is not located in the function table, the status given is:
|
// if a function is not located in the function table, the status given is:
|
||||||
// "hidden"+"local" (local means the function can be used only in this object file)
|
// "hidden"+"local" (local means the function can be used only in this object file)
|
||||||
procedure MatchExportNameToSymFlag(
|
procedure MatchExportNameToSymFlag(
|
||||||
x: TExportSection;
|
const imp: TImportSection;
|
||||||
l: TLinkingSection;
|
const c: TCodeSection;
|
||||||
e: TElementSection;
|
const e: TElementSection;
|
||||||
syms : TStrings)
|
const x: TExportSection;
|
||||||
|
var l: TLinkingSection; doVerbose: Boolean);
|
||||||
|
type
|
||||||
|
TFuncType = (ftImpl = 0, ftIntf, ftStub, ftExport);
|
||||||
|
|
||||||
|
TFuncInfo = record
|
||||||
|
hasSymbol : Boolean;
|
||||||
|
fnType : TFuncType;
|
||||||
|
end;
|
||||||
|
|
||||||
|
var
|
||||||
|
i : integer;
|
||||||
|
j : integer;
|
||||||
|
idx : integer;
|
||||||
|
fn : array of TFuncInfo;
|
||||||
|
codeofs: integer;
|
||||||
begin
|
begin
|
||||||
|
idx := -1;
|
||||||
|
for i:=0 to length(l.symbols)-1 do
|
||||||
|
if l.symbols[i].kind = SYMTAB_FUNCTION then begin
|
||||||
|
writeln(i,' fun idx: ', l.symbols[i].symindex);
|
||||||
|
if l.symbols[i].symindex>idx then begin
|
||||||
|
idx:= l.symbols[i].symindex;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
SetLength(fn, idx+1);
|
||||||
|
for i:=0 to length(l.symbols)-1 do
|
||||||
|
if l.symbols[i].kind = SYMTAB_FUNCTION then begin
|
||||||
|
idx := l.symbols[i].symindex;
|
||||||
|
fn[idx].hasSymbol:=true;
|
||||||
|
end;
|
||||||
|
|
||||||
|
for i:=0 to length(e.entries)-1 do
|
||||||
|
for j:=0 to length(e.entries[i].funcs)-1 do begin
|
||||||
|
idx := e.entries[i].funcs[j];
|
||||||
|
fn[idx].fnType:=ftIntf;
|
||||||
|
end;
|
||||||
|
|
||||||
|
codeofs:=0;
|
||||||
|
for i:=0 to length(imp.entries)-1 do
|
||||||
|
if imp.entries[i].desc = IMPDESC_FUNC then
|
||||||
|
inc(codeofs);
|
||||||
|
|
||||||
|
for i:=codeofs to length(fn)-1 do begin
|
||||||
|
if not fn[i].hasSymbol then begin
|
||||||
|
Continue;
|
||||||
|
end;
|
||||||
|
|
||||||
|
if (fn[i].fnType=ftImpl) and (isUnreachable(c.entries[i-codeofs])) then begin
|
||||||
|
fn[i].fnType:=ftStub;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
for i:=0 to length(x.entries)-1 do begin
|
||||||
|
if x.entries[i].desc = EXPDESC_FUNC then begin
|
||||||
|
idx := x.entries[i].index;
|
||||||
|
if fn[idx].fnType<>ftStub then
|
||||||
|
fn[idx].fnType:=ftExport;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
for i:=0 to length(l.symbols)-1 do begin
|
||||||
|
if l.symbols[i].kind = SYMTAB_FUNCTION then begin
|
||||||
|
j := l.symbols[i].symindex;
|
||||||
|
|
||||||
|
if j>=codeofs then // not imported
|
||||||
|
case fn[j].fnType of
|
||||||
|
ftImpl:
|
||||||
|
l.symbols[i].flags := l.symbols[i].flags or WASM_SYM_VISIBILITY_HIDDEN or WASM_SYM_BINDING_LOCAL;
|
||||||
|
ftIntf:
|
||||||
|
l.symbols[i].flags := l.symbols[i].flags or WASM_SYM_VISIBILITY_HIDDEN;
|
||||||
|
ftStub:
|
||||||
|
l.symbols[i].flags := l.symbols[i].flags or WASM_SYM_BINDING_WEAK or WASM_SYM_VISIBILITY_HIDDEN;
|
||||||
|
ftExport:
|
||||||
|
//l.symbols[i].flags := l.symbols[i].flags or WASM_SYM_VISIBILITY_HIDDEN or WASM_SYM_BINDING_WEAK;
|
||||||
|
;
|
||||||
|
end;
|
||||||
|
|
||||||
|
if DoVerbose then begin
|
||||||
|
write('func ');
|
||||||
|
if l.symbols[i].hasSymName then
|
||||||
|
write(l.symbols[i].symname)
|
||||||
|
else
|
||||||
|
write('#',j);
|
||||||
|
write(' ', fn[j].fnType);
|
||||||
|
writeln;
|
||||||
|
end;
|
||||||
|
//if l.symbols[i].symindex>mx then mx := ;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function PredictSymbolsFromLink(const wasmfn: string; syms: TStrings; doVerbose: Boolean = false): Boolean;
|
function PredictSymbolsFromLink(const wasmfn: string; doVerbose: Boolean = false): Boolean;
|
||||||
var
|
var
|
||||||
st : TFileStream;
|
st : TFileStream;
|
||||||
dw : LongWord;
|
dw : LongWord;
|
||||||
foundExport : Boolean;
|
foundCode : Boolean;
|
||||||
foundElement : Boolean;
|
foundElement : Boolean;
|
||||||
foundLink : Boolean;
|
foundLink : Boolean;
|
||||||
|
foundExport : Boolean;
|
||||||
|
foundImport : Boolean;
|
||||||
ofs : Int64;
|
ofs : Int64;
|
||||||
ps : Int64;
|
ps : Int64;
|
||||||
sc : TSection;
|
sc : TSection;
|
||||||
x : TExportSection;
|
c : TCodeSection;
|
||||||
|
imp : TImportSection;
|
||||||
l : TLinkingSection;
|
l : TLinkingSection;
|
||||||
e : TElementSection;
|
e : TElementSection;
|
||||||
cnt : Integer;
|
x : TExportSection;
|
||||||
nm : string;
|
nm : string;
|
||||||
|
lofs : Int64;
|
||||||
|
lsize : Int64;
|
||||||
|
mem : TMemoryStream;
|
||||||
|
mem2 : TMemoryStream;
|
||||||
begin
|
begin
|
||||||
st := TFileStream.Create(wasmfn, fmOpenRead or fmShareDenyNone);
|
st := TFileStream.Create(wasmfn, fmOpenReadWrite or fmShareDenyNone);
|
||||||
try
|
try
|
||||||
dw := st.ReadDWord;
|
dw := st.ReadDWord;
|
||||||
Result := dw = WasmId_Int;
|
Result := dw = WasmId_Int;
|
||||||
if not Result then begin
|
if not Result then Exit;
|
||||||
Exit;
|
|
||||||
end;
|
|
||||||
dw := st.ReadDWord;
|
dw := st.ReadDWord;
|
||||||
|
|
||||||
foundElement:=false;
|
foundElement := false;
|
||||||
foundExport:=false;
|
foundCode := false;
|
||||||
foundLink:=false;
|
foundLink := false;
|
||||||
|
foundExport := false;
|
||||||
|
foundImport := false;
|
||||||
|
Result := false;
|
||||||
while st.Position<st.Size do begin
|
while st.Position<st.Size do begin
|
||||||
ofs := st.Position;
|
ofs := st.Position;
|
||||||
sc.id := st.ReadByte;
|
sc.id := st.ReadByte;
|
||||||
@ -105,26 +206,76 @@ begin
|
|||||||
|
|
||||||
ps := st.Position+sc.size;
|
ps := st.Position+sc.size;
|
||||||
|
|
||||||
if sc.id = SECT_EXPORT then begin
|
case sc.id of
|
||||||
if doVerbose then writeln(' export section found');
|
SECT_IMPORT: begin
|
||||||
ReadExport(st, x);
|
ReadImportSection(st, imp);
|
||||||
cnt := ExportRenameSym(x, syms);
|
foundImport := true;
|
||||||
foundExport:=true;
|
end;
|
||||||
end else if sc.id = SECT_CUSTOM then begin
|
SECT_EXPORT: begin
|
||||||
nm := ReadName(st);
|
ReadExport(st, x);
|
||||||
if nm = SectionName_Linking then begin
|
foundExport := true;
|
||||||
foundLink := true;
|
end;
|
||||||
ReadLinkingSection(st, sc.size, l);
|
SECT_ELEMENT: begin
|
||||||
|
ReadElementSection(st, e);
|
||||||
|
foundElement := true;
|
||||||
|
end;
|
||||||
|
SECT_CODE: begin
|
||||||
|
ReadCodeSection(st, c);
|
||||||
|
foundCode := true;
|
||||||
|
end;
|
||||||
|
SECT_CUSTOM: begin
|
||||||
|
nm := ReadName(st);
|
||||||
|
if nm = SectionName_Linking then begin
|
||||||
|
lofs:=ofs;
|
||||||
|
ReadLinkingSection(st, sc.size, l);
|
||||||
|
foundLink := true;
|
||||||
|
lsize := ps-lofs;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if st.Position <> ps then
|
if st.Position <> ps then begin
|
||||||
st.Position := ps;
|
st.Position := ps;
|
||||||
|
end;
|
||||||
|
|
||||||
|
Result := foundLink and foundCode and foundElement;
|
||||||
|
if Result then break;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
Result := foundLink and foundExport;
|
if not foundExport then SetLength(x.entries,0);
|
||||||
if Result then
|
if not foundImport then SetLength(imp.entries, 0);
|
||||||
MatchExportNameToSymFlag(x, l, syms);
|
|
||||||
|
if Result then begin
|
||||||
|
if doVerbose then writeln('detecting symbols');
|
||||||
|
MatchExportNameToSymFlag(imp, c, e, x, l, doVerbose);
|
||||||
|
mem:=TMemoryStream.Create;
|
||||||
|
mem2:=TMemoryStream.Create;
|
||||||
|
try
|
||||||
|
st.Position:=lofs+lsize;
|
||||||
|
mem2.CopyFrom(st, st.Size - st.Position);
|
||||||
|
|
||||||
|
st.Position:=lofs;
|
||||||
|
WriteName(mem, SectionName_Linking);
|
||||||
|
WriteLinkingSection(mem, l);
|
||||||
|
|
||||||
|
st.WriteByte(SECT_CUSTOM);
|
||||||
|
if doVerbose then writeln('section size: ', mem.Size);
|
||||||
|
WriteU32(st, mem.Size);
|
||||||
|
|
||||||
|
mem.Position:=0;
|
||||||
|
if doVerbose then writeln('copying from mem');
|
||||||
|
st.CopyFrom(mem, mem.Size);
|
||||||
|
mem2.Position:=0;
|
||||||
|
if doVerbose then writeln('copying from mem2');
|
||||||
|
st.CopyFrom(mem2, mem2.Size);
|
||||||
|
st.Size:=st.Position;
|
||||||
|
finally
|
||||||
|
mem.Free;
|
||||||
|
mem2.Free;
|
||||||
|
end;
|
||||||
|
if doVerbose then writeln('written: ', st.Position-lofs,' bytes');
|
||||||
|
end else
|
||||||
|
writeln('failed. section find status. Likning: ', foundLink,'; Code: ', foundCode,'; Element: ', foundElement);
|
||||||
finally
|
finally
|
||||||
st.Free;
|
st.Free;
|
||||||
end;
|
end;
|
||||||
@ -139,13 +290,9 @@ begin
|
|||||||
fs := TFileStream.Create(fn, fmOpenReadWrite or fmShareDenyNone);
|
fs := TFileStream.Create(fn, fmOpenReadWrite or fmShareDenyNone);
|
||||||
try
|
try
|
||||||
if (symfn<>'') then begin
|
if (symfn<>'') then begin
|
||||||
if not isWasmFile(symfn) then
|
ReadSymbolsConf(symfn, syms);
|
||||||
ReadSymbolsConf(symfn, syms)
|
ChangeSymbolFlagStream(fs, syms);
|
||||||
else begin
|
|
||||||
PredictSymbolsFromLink(symfn, syms);
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
ChangeSymbolFlagStream(fs, syms);
|
|
||||||
finally
|
finally
|
||||||
fs.Free;
|
fs.Free;
|
||||||
syms.Free;
|
syms.Free;
|
||||||
|
Loading…
Reference in New Issue
Block a user