From 17ede9101807f8c2be26fa452f055b4920405ecc Mon Sep 17 00:00:00 2001 From: DQNEO Date: Thu, 6 Jul 2023 12:57:31 +0900 Subject: [PATCH] tmp --- encoder.go | 27 +++++++++++++---------- main.go | 65 +++++++++++++++++++++++++++++++++--------------------- 2 files changed, 55 insertions(+), 37 deletions(-) diff --git a/encoder.go b/encoder.go index 159e94f..84800c1 100644 --- a/encoder.go +++ b/encoder.go @@ -3,7 +3,6 @@ package main import ( "fmt" - "os" "strconv" "unsafe" ) @@ -148,16 +147,18 @@ type variableCode struct { } type Instruction struct { - addr uintptr - s *Stmt - index int - code []byte // fixed length code - varcode *variableCode - isLenDecided bool - next *Instruction + addr uintptr + symbolDefinition string + s *Stmt + index int + code []byte // fixed length code + varcode *variableCode + isLenDecided bool + next *Instruction + unresolvedCallTarget *callTarget } -var callTargets []*callTarget +//var callTargets []*callTarget type callTarget struct { trgtSymbol string @@ -167,12 +168,14 @@ type callTarget struct { } func registerCallTarget(caller *Instruction, trgtSymbol string, offset uintptr, width int) { - callTargets = append(callTargets, &callTarget{ + debugf("registering unresolved callTarget: %s\n", trgtSymbol) + ct := &callTarget{ trgtSymbol: trgtSymbol, caller: caller, offset: offset, width: width, - }) + } + caller.unresolvedCallTarget = ct } func calcDistance(userInstr *Instruction, symdef *symbolDefinition) (int, int, int, bool) { @@ -208,7 +211,7 @@ func calcDistance(userInstr *Instruction, symdef *symbolDefinition) (int, int, i } func appendRelaTextUser(ru *relaTextUser, stmt *Stmt) { - fmt.Fprintf(os.Stderr, "appending RU: %s from '%s'\n", ru.uses, stmt.source) + //fmt.Fprintf(os.Stderr, "appending RU: %s from '%s'\n", ru.uses, stmt.source) relaTextUsers = append(relaTextUsers, ru) } diff --git a/main.go b/main.go index e66b212..6e77f17 100644 --- a/main.go +++ b/main.go @@ -308,6 +308,8 @@ func isDataSymbolUsed(definedSymbols map[string]*symbolDefinition, relaTextUsers } func buildSymbolTable(addData bool, globalSymbols map[string]bool, symbolsInLexicalOrder []string) (uint32, []uint8, map[string]int) { + debugf("# Building symbol table ....\n") + var symbolIndex = make(map[string]int) var symbolTable = []*Elf64_Sym{ @@ -327,8 +329,8 @@ func buildSymbolTable(addData bool, globalSymbols map[string]bool, symbolsInLexi } var localSymbols []string - var globalDefinedSymbols []string - var globalUndefinedSymbols []string + var gss []string + for _, sym := range symbolsInLexicalOrder { if strings.HasPrefix(sym, ".L") { // https://sourceware.org/binutils/docs-2.37/as.html#Symbol-Names @@ -347,17 +349,19 @@ func buildSymbolTable(addData bool, globalSymbols map[string]bool, symbolsInLexi if !isGlobal { localSymbols = append(localSymbols, sym) } else { + debugf(" global symbol \"%s\"\n", sym) if isDefined { - globalDefinedSymbols = append(globalDefinedSymbols, sym) + gss = append(gss, sym) } else { - globalUndefinedSymbols = append(globalUndefinedSymbols, sym) + gss = append(gss, sym) } } } // local => global defined => global undefined - allSymbolsForElf := append(localSymbols, globalDefinedSymbols...) - allSymbolsForElf = append(allSymbolsForElf, globalUndefinedSymbols...) + var allSymbolsForElf []string = localSymbols + allSymbolsForElf = append(allSymbolsForElf, gss...) + // allSymbolsForElf = append(allSymbolsForElf, globalUndefinedSymbols...) s_strtab.contents = makeStrTab(allSymbolsForElf) @@ -505,7 +509,7 @@ func encodeAllText(ss []*Stmt) []byte { } instr := encode(s) if s.labelSymbol != "" { - definedSymbols[s.labelSymbol].instr = instr + instr.symbolDefinition = s.labelSymbol } insts = append(insts, instr) instr.index = index @@ -523,29 +527,42 @@ func encodeAllText(ss []*Stmt) []byte { variableInstrs = resolveVariableLengthInstrs(variableInstrs) } + var definedSymbolsStr = make(map[string]bool) var allText []byte var textAddr uintptr for instr := first; instr != nil; instr = instr.next { + // @TODO: + if instr.symbolDefinition != "" { + definedSymbolsStr[instr.symbolDefinition] = true + } + // resolve call targets instr.addr = textAddr allText = append(allText, instr.code...) textAddr += uintptr(len(instr.code)) - } - // Resolve call targets - for _, call := range callTargets { - callee, ok := definedSymbols[call.trgtSymbol] - if !ok { - continue + // Resolve call targets if needed + if instr.unresolvedCallTarget != nil { + call := instr.unresolvedCallTarget + callee, ok := definedSymbols[call.trgtSymbol] + if !ok { + debugf("UndefinedSymbol, keep call target zero %s\n", call.trgtSymbol) + } else { + debugf("reresolvedCallTarget: %s => %s\n", instr.code, callee.instr) + + diff := callee.instr.addr - call.caller.next.addr + placeToEmbed := call.caller.addr + call.offset + debugf("Resolving call target: \"%s\" diff=%04x (callee.addr %d - caller.nextAddr=%d)\n", + call.trgtSymbol, diff, callee.instr.addr, call.caller.next.addr) + diffInt32 := int32(diff) + var buf *[4]byte = (*[4]byte)(unsafe.Pointer(&diffInt32)) + allText[placeToEmbed] = buf[0] + allText[placeToEmbed+1] = buf[1] + allText[placeToEmbed+2] = buf[2] + allText[placeToEmbed+3] = buf[3] + } } - diff := callee.instr.addr - call.caller.next.addr - placeToEmbed := call.caller.addr + call.offset - diffInt32 := int32(diff) - var buf *[4]byte = (*[4]byte)(unsafe.Pointer(&diffInt32)) - allText[placeToEmbed] = buf[0] - allText[placeToEmbed+1] = buf[1] - allText[placeToEmbed+2] = buf[2] - allText[placeToEmbed+3] = buf[3] } + return allText } @@ -666,9 +683,7 @@ func buildRelaTextBody(symbolIndex map[string]int) []byte { sym, defined := definedSymbols[ru.uses] var addr int64 if defined { - // skip symbols that belong to the same section - // ^ why ??? - if sym.section == ".text" { + if false { // @TODO in some cases, it should be added int Rela continue } addr = int64(sym.address) @@ -693,7 +708,7 @@ func buildRelaTextBody(symbolIndex map[string]int) []byte { r_info: uint64(symIdx)<<32 + typ, r_addend: addr + ru.adjust - 4, } - println("writing relaText", i, ru.uses) + //debugf("--- writing relaText [%d] %s \n", i, ru.uses) p := (*[unsafe.Sizeof(Elf64_Rela{})]byte)(unsafe.Pointer(rela))[:] contents = append(contents, p...) }