summaryrefslogtreecommitdiffstats
path: root/linker
diff options
context:
space:
mode:
authorRaghu Gandham <raghu@mips.com>2012-07-31 12:07:22 -0700
committerElliott Hughes <enh@google.com>2012-08-02 14:39:50 -0700
commitd7daacb46372132ae3f0121647074936c304b572 (patch)
treec6bbaccbf2d36b1c4494b5bce7e7b489bec6442b /linker
parent0ca9d0748e3229c849e3ee17259e0e55d7214800 (diff)
downloadbionic-d7daacb46372132ae3f0121647074936c304b572.zip
bionic-d7daacb46372132ae3f0121647074936c304b572.tar.gz
bionic-d7daacb46372132ae3f0121647074936c304b572.tar.bz2
MIPS support to the linker
Change-Id: I37ec2d6c51d82bb9e9dbfef4b38c85366bead255 Signed-off-by: Chris Dearman <chris@mips.com> Signed-off-by: Raghu Gandham <raghu@mips.com> Signed-off-by: Bhanu Chetlapalli <bhanu@mips.com>
Diffstat (limited to 'linker')
-rw-r--r--linker/Android.mk15
-rw-r--r--linker/arch/mips/begin.S107
-rw-r--r--linker/debugger.c6
-rw-r--r--linker/dlfcn.c6
-rw-r--r--linker/linker.c177
-rw-r--r--linker/linker.h42
-rw-r--r--linker/linker_format.c14
7 files changed, 311 insertions, 56 deletions
diff --git a/linker/Android.mk b/linker/Android.mk
index c9d053f..d207f95 100644
--- a/linker/Android.mk
+++ b/linker/Android.mk
@@ -16,7 +16,8 @@ LOCAL_LDFLAGS := -shared
LOCAL_CFLAGS += -fno-stack-protector \
-Wstrict-overflow=5 \
-fvisibility=hidden \
- -std=gnu99
+ -std=gnu99 \
+ -Wall -Wextra
# Set LINKER_DEBUG to either 1 or 0
#
@@ -33,11 +34,15 @@ LOCAL_CFLAGS += \
-I$(LOCAL_PATH)/../libc/arch-$(TARGET_ARCH)/bionic
ifeq ($(TARGET_ARCH),arm)
-LOCAL_CFLAGS += -DANDROID_ARM_LINKER
-else
- ifeq ($(TARGET_ARCH),x86)
+ LOCAL_CFLAGS += -DANDROID_ARM_LINKER
+endif
+
+ifeq ($(TARGET_ARCH),x86)
LOCAL_CFLAGS += -DANDROID_X86_LINKER
- endif
+endif
+
+ifeq ($(TARGET_ARCH),mips)
+ LOCAL_CFLAGS += -DANDROID_MIPS_LINKER
endif
LOCAL_MODULE:= linker
diff --git a/linker/arch/mips/begin.S b/linker/arch/mips/begin.S
new file mode 100644
index 0000000..b782947
--- /dev/null
+++ b/linker/arch/mips/begin.S
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+ .text
+ .align 4
+ .type __start,@function
+
+ .ent __start
+ .globl __start
+__start:
+ .set noreorder
+ bal 1f
+ nop
+1: .cpload $31
+ .set reorder
+
+ /* Discover the load address */
+ la $t0, 1f
+ bal 1f
+1: subu $t0, $ra, $t0
+
+#define DT_PLTGOT 3
+#define DT_MIPS_LOCAL_GOTNO 0x7000000a
+
+ /* Search dynamic table for DT_MIPS_LOCAL_GOTNO and DT_PLTGOT values */
+ la $t1, _DYNAMIC
+ addu $t1, $t0
+ li $t3, DT_PLTGOT
+ li $t4, DT_MIPS_LOCAL_GOTNO
+0:
+ lw $t2, 0($t1)
+ beqz $t2, .Lrelocate_local_got
+
+ bne $t2, $t3, 1f /* DT_PLTGOT? */
+ lw $s0, 4($t1)
+ addu $s0, $t0
+ b 2f
+
+1: bne $t2, $t4, 1f /* DT_MIPS_LOCAL_GOTNO? */
+ lw $s1, 4($t1)
+ b 2f
+
+1:
+2: addu $t1, 8
+ b 0b
+
+.Lrelocate_local_got:
+ /*
+ * Relocate the local GOT entries
+ * got[0] is address of lazy resolver function
+ * got[1] may be used for a GNU extension
+ */
+
+ addu $s0, 4
+ subu $s1, 1
+ lw $t1, ($s0)
+ bgez $t1, 9f
+ addu $s0, 4
+ subu $s1, 1
+ b 9f
+
+1: lw $t1, ($s0)
+ addu $t1, $t0
+ sw $t1, ($s0)
+ addu $s0, 4
+9: subu $s1, 1
+ bgez $s1, 1b
+
+ /* call linker_init */
+ move $a0, $sp
+ addiu $sp, -4*4 /* space for arg saves in linker_init */
+ la $t9, __linker_init
+ jalr $t9
+ move $t9, $v0
+ addu $sp, 4*4 /* restore sp */
+ j $t9
+ .end __start
+
+ .section .ctors, "wa"
+ .globl __CTOR_LIST__
+__CTOR_LIST__:
+ .long -1
diff --git a/linker/debugger.c b/linker/debugger.c
index 756b5cf..7a1dd15 100644
--- a/linker/debugger.c
+++ b/linker/debugger.c
@@ -131,7 +131,9 @@ static void logSignalSummary(int signum, const siginfo_t* info)
case SIGBUS: signame = "SIGBUS"; break;
case SIGFPE: signame = "SIGFPE"; break;
case SIGSEGV: signame = "SIGSEGV"; break;
+#if defined(SIGSTKFLT)
case SIGSTKFLT: signame = "SIGSTKFLT"; break;
+#endif
case SIGPIPE: signame = "SIGPIPE"; break;
default: signame = "???"; break;
}
@@ -214,7 +216,9 @@ void debugger_signal_handler(int n, siginfo_t* info, void* unused)
case SIGABRT:
case SIGFPE:
case SIGPIPE:
+#ifdef SIGSTKFLT
case SIGSTKFLT:
+#endif
(void) tgkill(getpid(), gettid(), n);
break;
default: // SIGILL, SIGBUS, SIGSEGV
@@ -235,6 +239,8 @@ void debugger_init()
sigaction(SIGBUS, &act, NULL);
sigaction(SIGFPE, &act, NULL);
sigaction(SIGSEGV, &act, NULL);
+#if defined(SIGSTKFLT)
sigaction(SIGSTKFLT, &act, NULL);
+#endif
sigaction(SIGPIPE, &act, NULL);
}
diff --git a/linker/dlfcn.c b/linker/dlfcn.c
index 3d0384f..13064e5 100644
--- a/linker/dlfcn.c
+++ b/linker/dlfcn.c
@@ -170,13 +170,13 @@ int dlclose(void *handle)
#define ANDROID_LIBDL_STRTAB \
"dlopen\0dlclose\0dlsym\0dlerror\0dladdr\0dl_unwind_find_exidx\0"
-#elif defined(ANDROID_X86_LINKER)
+#elif defined(ANDROID_X86_LINKER) || defined(ANDROID_MIPS_LINKER)
// 0000000 00011111 111112 22222222 2333333 3333444444444455
// 0123456 78901234 567890 12345678 9012345 6789012345678901
#define ANDROID_LIBDL_STRTAB \
"dlopen\0dlclose\0dlsym\0dlerror\0dladdr\0dl_iterate_phdr\0"
#else
-#error Unsupported architecture. Only ARM and x86 are presently supported.
+#error Unsupported architecture. Only ARM, MIPS, and x86 are presently supported.
#endif
@@ -218,7 +218,7 @@ static Elf32_Sym libdl_symtab[] = {
st_info: STB_GLOBAL << 4,
st_shndx: 1,
},
-#elif defined(ANDROID_X86_LINKER)
+#elif defined(ANDROID_X86_LINKER) || defined(ANDROID_MIPS_LINKER)
{ st_name: 36,
st_value: (Elf32_Addr) &dl_iterate_phdr,
st_info: STB_GLOBAL << 4,
diff --git a/linker/linker.c b/linker/linker.c
index 0a93130..e0c3bce 100644
--- a/linker/linker.c
+++ b/linker/linker.c
@@ -142,9 +142,9 @@ static char tmp_err_buf[768];
static char __linker_dl_err_buf[768];
#define DL_ERR(fmt, x...) \
do { \
- format_buffer(__linker_dl_err_buf, sizeof(__linker_dl_err_buf), \
+ format_buffer(__linker_dl_err_buf, sizeof(__linker_dl_err_buf), \
"%s[%d]: " fmt, __func__, __LINE__, ##x); \
- ERROR(fmt "\n", ##x); \
+ ERROR(fmt "\n", ##x); \
} while(0)
const char *linker_get_error(void)
@@ -350,7 +350,7 @@ _Unwind_Ptr dl_unwind_find_exidx(_Unwind_Ptr pc, int *pcount)
*pcount = 0;
return NULL;
}
-#elif defined(ANDROID_X86_LINKER)
+#elif defined(ANDROID_X86_LINKER) || defined(ANDROID_MIPS_LINKER)
/* Here, we only have to provide a callback to iterate across all the
* loaded libraries. gcc_eh does the rest. */
int
@@ -455,7 +455,7 @@ soinfo_do_lookup(soinfo *si, const char *name, Elf32_Addr *offset)
lsi = (soinfo *)d[1];
if (!validate_soinfo(lsi)) {
DL_ERR("%5d bad DT_NEEDED pointer in %s",
- pid, si->name);
+ pid, lsi->name);
return NULL;
}
@@ -691,6 +691,8 @@ verify_elf_header(const Elf32_Ehdr* hdr)
if (hdr->e_machine != EM_ARM) return -1;
#elif defined(ANDROID_X86_LINKER)
if (hdr->e_machine != EM_386) return -1;
+#elif defined(ANDROID_MIPS_LINKER)
+ if (hdr->e_machine != EM_MIPS) return -1;
#endif
return 0;
}
@@ -975,7 +977,7 @@ static int soinfo_relocate(soinfo *si, Elf32_Rel *rel, unsigned count)
Elf32_Rel *start = rel;
unsigned idx;
- for (idx = 0; idx < count; ++idx) {
+ for (idx = 0; idx < count; ++idx, ++rel) {
unsigned type = ELF32_R_TYPE(rel->r_info);
unsigned sym = ELF32_R_SYM(rel->r_info);
unsigned reloc = (unsigned)(rel->r_offset + si->load_bias);
@@ -984,6 +986,9 @@ static int soinfo_relocate(soinfo *si, Elf32_Rel *rel, unsigned count)
DEBUG("%5d Processing '%s' relocation at index %d\n", pid,
si->name, idx);
+ if (type == 0) { // R_*_NONE
+ continue;
+ }
if(sym != 0) {
sym_name = (char *)(strtab + symtab[sym].st_name);
s = soinfo_do_lookup(si, sym_name, &offset);
@@ -1015,9 +1020,8 @@ static int soinfo_relocate(soinfo *si, Elf32_Rel *rel, unsigned count)
case R_ARM_GLOB_DAT:
case R_ARM_ABS32:
case R_ARM_RELATIVE: /* Don't care. */
- case R_ARM_NONE: /* Don't care. */
#elif defined(ANDROID_X86_LINKER)
- case R_386_JUMP_SLOT:
+ case R_386_JMP_SLOT:
case R_386_GLOB_DAT:
case R_386_32:
case R_386_RELATIVE: /* Dont' care. */
@@ -1046,15 +1050,15 @@ static int soinfo_relocate(soinfo *si, Elf32_Rel *rel, unsigned count)
} else {
/* We got a definition. */
#if 0
- if((base == 0) && (si->base != 0)){
- /* linking from libraries to main image is bad */
- DL_ERR("%5d cannot locate '%s'...",
- pid, strtab + symtab[sym].st_name);
- return -1;
- }
+ if((base == 0) && (si->base != 0)){
+ /* linking from libraries to main image is bad */
+ DL_ERR("%5d cannot locate '%s'...",
+ pid, strtab + symtab[sym].st_name);
+ return -1;
+ }
#endif
sym_addr = (unsigned)(s->st_value + offset);
- }
+ }
COUNT_RELOC(RELOC_SYMBOL);
} else {
s = NULL;
@@ -1094,7 +1098,7 @@ static int soinfo_relocate(soinfo *si, Elf32_Rel *rel, unsigned count)
*((unsigned*)reloc) += sym_addr - rel->r_offset;
break;
#elif defined(ANDROID_X86_LINKER)
- case R_386_JUMP_SLOT:
+ case R_386_JMP_SLOT:
COUNT_RELOC(RELOC_ABSOLUTE);
MARK(rel->r_offset);
TRACE_TYPE(RELO, "%5d RELO JMP_SLOT %08x <- %08x %s\n", pid,
@@ -1108,6 +1112,25 @@ static int soinfo_relocate(soinfo *si, Elf32_Rel *rel, unsigned count)
reloc, sym_addr, sym_name);
*((unsigned*)reloc) = sym_addr;
break;
+#elif defined(ANDROID_MIPS_LINKER)
+ case R_MIPS_JUMP_SLOT:
+ COUNT_RELOC(RELOC_ABSOLUTE);
+ MARK(rel->r_offset);
+ TRACE_TYPE(RELO, "%5d RELO JMP_SLOT %08x <- %08x %s\n", pid,
+ reloc, sym_addr, sym_name);
+ *((unsigned*)reloc) = sym_addr;
+ break;
+ case R_MIPS_REL32:
+ COUNT_RELOC(RELOC_ABSOLUTE);
+ MARK(rel->r_offset);
+ TRACE_TYPE(RELO, "%5d RELO REL32 %08x <- %08x %s\n", pid,
+ reloc, sym_addr, (sym_name) ? sym_name : "*SECTIONHDR*");
+ if (s) {
+ *((unsigned*)reloc) += sym_addr;
+ } else {
+ *((unsigned*)reloc) += si->base;
+ }
+ break;
#endif /* ANDROID_*_LINKER */
#if defined(ANDROID_ARM_LINKER)
@@ -1154,8 +1177,6 @@ static int soinfo_relocate(soinfo *si, Elf32_Rel *rel, unsigned count)
reloc, s->st_size, sym_addr, sym_name);
memcpy((void*)reloc, (void*)sym_addr, s->st_size);
break;
- case R_ARM_NONE:
- break;
#endif /* ANDROID_ARM_LINKER */
default:
@@ -1163,11 +1184,79 @@ static int soinfo_relocate(soinfo *si, Elf32_Rel *rel, unsigned count)
pid, type, rel, (int) (rel - start));
return -1;
}
- rel++;
}
return 0;
}
+#ifdef ANDROID_MIPS_LINKER
+int mips_relocate_got(struct soinfo *si)
+{
+ unsigned *got;
+ unsigned local_gotno, gotsym, symtabno;
+ Elf32_Sym *symtab, *sym;
+ unsigned g;
+
+ got = si->plt_got;
+ local_gotno = si->mips_local_gotno;
+ gotsym = si->mips_gotsym;
+ symtabno = si->mips_symtabno;
+ symtab = si->symtab;
+
+ /*
+ * got[0] is address of lazy resolver function
+ * got[1] may be used for a GNU extension
+ * set it to a recognisable address in case someone calls it
+ * (should be _rtld_bind_start)
+ * FIXME: maybe this should be in a separate routine
+ */
+
+ if ((si->flags & FLAG_LINKER) == 0) {
+ g = 0;
+ got[g++] = 0xdeadbeef;
+ if (got[g] & 0x80000000) {
+ got[g++] = 0xdeadfeed;
+ }
+ /*
+ * Relocate the local GOT entries need to be relocated
+ */
+ for (; g < local_gotno; g++) {
+ got[g] += si->load_bias;
+ }
+ }
+
+ /* Now for the global GOT entries */
+ sym = symtab + gotsym;
+ got = si->plt_got + local_gotno;
+ for (g = gotsym; g < symtabno; g++, sym++, got++) {
+ const char *sym_name;
+ unsigned base;
+ Elf32_Sym *s;
+
+ /* This is an undefined reference... try to locate it */
+ sym_name = si->strtab + sym->st_name;
+ s = soinfo_do_lookup(si, sym_name, &base);
+ if (s == NULL) {
+ /* We only allow an undefined symbol if this is a weak
+ reference.. */
+ s = &symtab[g];
+ if (ELF32_ST_BIND(s->st_info) != STB_WEAK) {
+ DL_ERR("%5d cannot locate '%s'...\n", pid, sym_name);
+ return -1;
+ }
+ *got = 0;
+ }
+ else {
+ /* FIXME: is this sufficient?
+ * For reference see NetBSD link loader
+ * http://cvsweb.netbsd.org/bsdweb.cgi/src/libexec/ld.elf_so/arch/mips/mips_reloc.c?rev=1.53&content-type=text/x-cvsweb-markup
+ */
+ *got = base + s->st_value;
+ }
+ }
+ return 0;
+}
+#endif
+
/* Please read the "Initialization and Termination functions" functions.
* of the linker design note in bionic/linker/README.TXT to understand
* what the following code is doing.
@@ -1442,8 +1531,10 @@ static int soinfo_link_image(soinfo *si, unsigned wr_offset)
si->plt_got = (unsigned *)(base + *d);
break;
case DT_DEBUG:
+#if !defined(ANDROID_MIPS_LINKER)
// Set the DT_DEBUG entry to the addres of _r_debug for GDB
*d = (int) &_r_debug;
+#endif
break;
case DT_RELA:
DL_ERR("%5d DT_RELA not supported", pid);
@@ -1491,6 +1582,50 @@ static int soinfo_link_image(soinfo *si, unsigned wr_offset)
DEBUG("%5d Text segment should be writable during relocation.\n",
pid);
break;
+#if defined(ANDROID_MIPS_LINKER)
+ case DT_NEEDED:
+ case DT_STRSZ:
+ case DT_SYMENT:
+ case DT_RELENT:
+ break;
+ case DT_MIPS_RLD_MAP:
+ /* Set the DT_MIPS_RLD_MAP entry to the addres of _r_debug for GDB */
+ {
+ struct r_debug **dp = (struct r_debug **)*d;
+ *dp = &_r_debug;
+ }
+ break;
+ case DT_MIPS_RLD_VERSION:
+ case DT_MIPS_FLAGS:
+ case DT_MIPS_BASE_ADDRESS:
+ case DT_MIPS_UNREFEXTNO:
+ case DT_MIPS_RWPLT:
+ break;
+
+ case DT_MIPS_PLTGOT:
+#if 0
+ /* not yet... */
+ si->mips_pltgot = (unsigned *)(si->base + *d);
+#endif
+ break;
+
+ case DT_MIPS_SYMTABNO:
+ si->mips_symtabno = *d;
+ break;
+
+ case DT_MIPS_LOCAL_GOTNO:
+ si->mips_local_gotno = *d;
+ break;
+
+ case DT_MIPS_GOTSYM:
+ si->mips_gotsym = *d;
+ break;
+
+ default:
+ DEBUG("%5d Unused DT entry: type 0x%08x arg 0x%08x\n",
+ pid, d[-1], d[0]);
+ break;
+#endif
}
}
@@ -1552,6 +1687,12 @@ static int soinfo_link_image(soinfo *si, unsigned wr_offset)
goto fail;
}
+#ifdef ANDROID_MIPS_LINKER
+ if(mips_relocate_got(si)) {
+ goto fail;
+ }
+#endif
+
si->flags |= FLAG_LINKED;
DEBUG("[ %5d finished linking %s ]\n", pid, si->name);
diff --git a/linker/linker.h b/linker/linker.h
index 0956ac5..cb2eab6 100644
--- a/linker/linker.h
+++ b/linker/linker.h
@@ -150,11 +150,19 @@ struct soinfo
void (*init_func)(void);
void (*fini_func)(void);
-#ifdef ANDROID_ARM_LINKER
+#if defined(ANDROID_ARM_LINKER)
/* ARM EABI section used for stack unwinding. */
unsigned *ARM_exidx;
unsigned ARM_exidx_count;
+#elif defined(ANDROID_MIPS_LINKER)
+#if 0
+ /* not yet */
+ unsigned *mips_pltgot
#endif
+ unsigned mips_symtabno;
+ unsigned mips_local_gotno;
+ unsigned mips_gotsym;
+#endif /* ANDROID_*_LINKER */
unsigned refcount;
struct link_map linkmap;
@@ -169,29 +177,31 @@ struct soinfo
extern soinfo libdl_info;
-#ifdef ANDROID_ARM_LINKER
+#include <asm/elf.h>
+
+#if defined(ANDROID_ARM_LINKER)
+
+// These aren't defined in <arch-arm/asm/elf.h>.
+#define R_ARM_REL32 3
#define R_ARM_COPY 20
#define R_ARM_GLOB_DAT 21
#define R_ARM_JUMP_SLOT 22
#define R_ARM_RELATIVE 23
-/* According to the AAPCS specification, we only
- * need the above relocations. However, in practice,
- * the following ones turn up from time to time.
- */
-#define R_ARM_ABS32 2
-#define R_ARM_REL32 3
+#elif defined(ANDROID_MIPS_LINKER)
+
+// These aren't defined in <arch-arm/mips/elf.h>.
+#define R_MIPS_JUMP_SLOT 127
+
+#define DT_MIPS_PLTGOT 0x70000032
+#define DT_MIPS_RWPLT 0x70000034
#elif defined(ANDROID_X86_LINKER)
-#define R_386_32 1
-#define R_386_PC32 2
-#define R_386_GLOB_DAT 6
-#define R_386_JUMP_SLOT 7
-#define R_386_RELATIVE 8
+// x86 has everything it needs in <arch-arm/x86/elf.h>.
-#endif
+#endif /* ANDROID_*_LINKER */
#ifndef DT_INIT_ARRAY
#define DT_INIT_ARRAY 25
@@ -227,10 +237,10 @@ Elf32_Sym *soinfo_find_symbol(soinfo* si, const void *addr);
Elf32_Sym *soinfo_lookup(soinfo *si, const char *name);
void soinfo_call_constructors(soinfo *si);
-#ifdef ANDROID_ARM_LINKER
+#if defined(ANDROID_ARM_LINKER)
typedef long unsigned int *_Unwind_Ptr;
_Unwind_Ptr dl_unwind_find_exidx(_Unwind_Ptr pc, int *pcount);
-#elif defined(ANDROID_X86_LINKER)
+#elif defined(ANDROID_X86_LINKER) || defined(ANDROID_MIPS_LINKER)
int dl_iterate_phdr(int (*cb)(struct dl_phdr_info *, size_t, void *), void *);
#endif
diff --git a/linker/linker_format.c b/linker/linker_format.c
index cded68a..d305740 100644
--- a/linker/linker_format.c
+++ b/linker/linker_format.c
@@ -413,20 +413,6 @@ format_integer(char *buffer, size_t buffsize, uint64_t value, int base, int isSi
format_number(buffer, buffsize, value, base, "0123456789");
}
-/* Write an octal into a buffer, assumes buffsize > 2 */
-static void
-format_octal(char *buffer, size_t buffsize, uint64_t value, int isSigned)
-{
- format_integer(buffer, buffsize, value, 8, isSigned);
-}
-
-/* Write a decimal into a buffer, assumes buffsize > 2 */
-static void
-format_decimal(char *buffer, size_t buffsize, uint64_t value, int isSigned)
-{
- format_integer(buffer, buffsize, value, 10, isSigned);
-}
-
/* Write an hexadecimal into a buffer, isCap is true for capital alphas.
* Assumes bufsize > 2 */
static void