summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--erts/emulator/beam/atom.c2
-rw-r--r--erts/emulator/beam/beam_file.c101
-rw-r--r--erts/emulator/beam/beam_file.h4
-rw-r--r--erts/emulator/beam/beam_ranges.c9
-rw-r--r--erts/emulator/beam/bif.c2
-rw-r--r--erts/emulator/beam/binary.c2
-rw-r--r--erts/emulator/beam/emu/emu_load.c9
-rw-r--r--erts/emulator/beam/erl_binary.h2
-rw-r--r--erts/emulator/beam/erl_global_literals.h7
-rw-r--r--erts/emulator/beam/erl_init.c1
-rw-r--r--erts/emulator/beam/erl_unicode.c56
-rw-r--r--erts/emulator/beam/erl_unicode.h2
-rw-r--r--erts/emulator/beam/global.h13
-rw-r--r--erts/emulator/beam/jit/asm_load.c21
-rw-r--r--erts/emulator/beam/utils.c10
-rw-r--r--erts/etc/unix/etp-commands.in8
16 files changed, 150 insertions, 99 deletions
diff --git a/erts/emulator/beam/atom.c b/erts/emulator/beam/atom.c
index bcbed7746b..5083558b3a 100644
--- a/erts/emulator/beam/atom.c
+++ b/erts/emulator/beam/atom.c
@@ -305,7 +305,7 @@ erts_atom_put_index(const byte *name, Sint len, ErtsAtomEncoding enc, int trunc)
if (enc == ERTS_ATOM_ENC_UTF8) {
/* Need to verify encoding and length */
- byte *err_pos;
+ const byte *err_pos;
Uint no_chars;
switch (erts_analyze_utf8_x((byte *) text,
(Uint) tlen,
diff --git a/erts/emulator/beam/beam_file.c b/erts/emulator/beam/beam_file.c
index 2148e037ad..183bb1696f 100644
--- a/erts/emulator/beam/beam_file.c
+++ b/erts/emulator/beam/beam_file.c
@@ -26,6 +26,9 @@
#include "beam_load.h"
#include "erl_zlib.h"
#include "big.h"
+#include "erl_unicode.h"
+#include "erl_binary.h"
+#include "erl_global_literals.h"
#define LoadError(Expr) \
do { \
@@ -446,6 +449,10 @@ static int parse_line_chunk(BeamFile *beam, IFF_Chunk *chunk) {
LoadAssert(CHECK_ITEM_COUNT(item_count, 0, sizeof(lines->items[0])));
LoadAssert(CHECK_ITEM_COUNT(name_count, 0, sizeof(lines->names[0])));
+ /* Include the implicit "module name with .erl suffix" entry so we don't
+ * have to special-case it anywhere else. */
+ name_count++;
+
/* Flags are unused at the moment. */
(void)flags;
@@ -458,17 +465,20 @@ static int parse_line_chunk(BeamFile *beam, IFF_Chunk *chunk) {
item_count * sizeof(lines->items[0]));
lines->item_count = item_count;
- lines->names = erts_alloc(ERTS_ALC_T_PREPARED_CODE,
- name_count * sizeof(lines->names[0]));
- lines->name_count = name_count;
-
- lines->location_size = lines->name_count ? sizeof(Sint32) : sizeof(Sint16);
-
/* The zeroth entry in the line item table is always present and contains
* the "undefined location." */
lines->items[0].name_index = 0;
lines->items[0].location = 0;
+ lines->names = erts_alloc(ERTS_ALC_T_PREPARED_CODE,
+ name_count * sizeof(lines->names[0]));
+ lines->name_count = name_count;
+
+ /* We have to use the 32-bit representation if there's any names other than
+ * the implicit "module_name.erl" in the table, as we can't fit LOC_FILE in
+ * 16 bits. */
+ lines->location_size = name_count > 1 ? sizeof(Sint32) : sizeof(Sint16);
+
name_index = 0;
i = 1;
@@ -494,6 +504,8 @@ static int parse_line_chunk(BeamFile *beam, IFF_Chunk *chunk) {
lines->location_size = sizeof(Sint32);
}
+ LoadAssert(IS_VALID_LOCATION(name_index, val.word_value));
+
lines->items[i].location = val.word_value;
lines->items[i].name_index = name_index;
i++;
@@ -504,18 +516,67 @@ static int parse_line_chunk(BeamFile *beam, IFF_Chunk *chunk) {
}
}
- for (i = 0; i < name_count; i++) {
- Sint16 name_length;
- const byte *name_data;
- Eterm name;
+ /* Add the implicit "module_name.erl" entry, followed by the rest of the
+ * name table. */
+ {
+ Eterm default_name_buf[MAX_ATOM_CHARACTERS * 2];
+ Eterm *name_heap = default_name_buf;
+ Eterm name, suffix;
+ Eterm *hp;
+
+ suffix = erts_get_global_literal(ERTS_LIT_ERL_FILE_SUFFIX);
+
+ hp = name_heap;
+ name = erts_atom_to_string(&hp, beam->module, suffix);
+
+ lines->names[0] = beamfile_add_literal(beam, name);
- LoadAssert(beamreader_read_i16(&reader, &name_length));
- LoadAssert(beamreader_read_bytes(&reader, name_length, &name_data));
+ for (i = 1; i < name_count; i++) {
+ Uint num_chars, num_built, num_eaten;
+ const byte *name_data, *err_pos;
+ Sint16 name_length;
+ Eterm *hp;
- name = erts_atom_put(name_data, name_length, ERTS_ATOM_ENC_UTF8, 1);
- LoadAssert(name != THE_NON_VALUE);
+ LoadAssert(beamreader_read_i16(&reader, &name_length));
+ LoadAssert(name_length >= 0);
- lines->names[i] = name;
+ LoadAssert(beamreader_read_bytes(&reader, name_length, &name_data));
+
+ if (name_length > 0) {
+ LoadAssert(erts_analyze_utf8(name_data, name_length,
+ &err_pos, &num_chars,
+ NULL) == ERTS_UTF8_OK);
+
+ if (num_chars < MAX_ATOM_CHARACTERS) {
+ name_heap = default_name_buf;
+ } else {
+ name_heap = erts_alloc(ERTS_ALC_T_LOADER_TMP,
+ num_chars * sizeof(Eterm[2]));
+ }
+
+ hp = name_heap;
+ name = erts_make_list_from_utf8_buf(&hp, num_chars,
+ name_data,
+ name_length,
+ &num_built,
+ &num_eaten,
+ NIL);
+
+ ASSERT(num_built == num_chars);
+ ASSERT(num_eaten == name_length);
+
+ lines->names[i] = beamfile_add_literal(beam, name);
+
+ if (name_heap != default_name_buf) {
+ erts_free(ERTS_ALC_T_LOADER_TMP, name_heap);
+ }
+ } else {
+ /* Empty file names are rather unusual and annoying to deal
+ * with since NIL isn't a valid literal, so we'll fake it with
+ * our module name instead. */
+ lines->names[i] = lines->names[0];
+ }
+ }
}
return 1;
@@ -1127,6 +1188,16 @@ int iff_read_chunk(IFF_File *iff, Uint id, IFF_Chunk *chunk)
return read_beam_chunks(iff, 1, &id, chunk);
}
+void beamfile_init() {
+ Eterm suffix;
+ Eterm *hp;
+
+ hp = erts_alloc_global_literal(ERTS_LIT_ERL_FILE_SUFFIX, 8);
+ suffix = erts_bin_bytes_to_list(NIL, hp, (byte*)".erl", 4, 0);
+
+ erts_register_global_literal(ERTS_LIT_ERL_FILE_SUFFIX, suffix);
+}
+
/* * * * * * * */
void beamopallocator_init(BeamOpAllocator *allocator) {
diff --git a/erts/emulator/beam/beam_file.h b/erts/emulator/beam/beam_file.h
index 91b3d5e149..51e3a48c89 100644
--- a/erts/emulator/beam/beam_file.h
+++ b/erts/emulator/beam/beam_file.h
@@ -116,7 +116,7 @@ typedef struct {
Sint32 flags;
Sint32 name_count;
- Eterm *names;
+ Sint *names;
Sint32 location_size;
Sint32 item_count;
@@ -231,6 +231,8 @@ typedef struct {
#include "erl_process.h"
#include "erl_message.h"
+void beamfile_init(void);
+
/** @brief Reads the given module binary into \p beam and validates its
* structural integrity. */
enum beamfile_read_result
diff --git a/erts/emulator/beam/beam_ranges.c b/erts/emulator/beam/beam_ranges.c
index d90ee41bae..6c497bc61f 100644
--- a/erts/emulator/beam/beam_ranges.c
+++ b/erts/emulator/beam/beam_ranges.c
@@ -346,7 +346,6 @@ lookup_loc(FunctionInfo* fi, const void* pc,
if (pc < mid[0]) {
high = mid;
} else if (pc < mid[1]) {
- int file;
int index = mid - lt->func_tab[0];
if (lt->loc_size == 2) {
@@ -359,14 +358,6 @@ lookup_loc(FunctionInfo* fi, const void* pc,
return;
}
fi->needed += 3+2+3+2;
- file = LOC_FILE(fi->loc);
- if (file == 0) {
- /* Special case: Module name with ".erl" appended */
- Atom* mod_atom = atom_tab(atom_val(fi->mfa->module));
- fi->needed += 2*(mod_atom->len+4);
- } else {
- fi->needed += 2*erts_atom_to_string_length((fi->fname_ptr)[file-1]);
- }
return;
} else {
low = mid + 1;
diff --git a/erts/emulator/beam/bif.c b/erts/emulator/beam/bif.c
index d56574b27b..b67ad8f531 100644
--- a/erts/emulator/beam/bif.c
+++ b/erts/emulator/beam/bif.c
@@ -3162,7 +3162,7 @@ BIF_RETTYPE atom_to_list_1(BIF_ALIST_1)
{
Atom* ap;
Uint num_chars, num_built, num_eaten;
- byte* err_pos;
+ const byte* err_pos;
Eterm res;
int ares;
diff --git a/erts/emulator/beam/binary.c b/erts/emulator/beam/binary.c
index 39ca0827ca..a006553ef3 100644
--- a/erts/emulator/beam/binary.c
+++ b/erts/emulator/beam/binary.c
@@ -241,7 +241,7 @@ erts_get_aligned_binary_bytes_extra(Eterm bin, byte** base_ptr, ErtsAlcType_t al
}
Eterm
-erts_bin_bytes_to_list(Eterm previous, Eterm* hp, byte* bytes, Uint size, Uint bitoffs)
+erts_bin_bytes_to_list(Eterm previous, Eterm* hp, const byte* bytes, Uint size, Uint bitoffs)
{
if (bitoffs == 0) {
while (size) {
diff --git a/erts/emulator/beam/emu/emu_load.c b/erts/emulator/beam/emu/emu_load.c
index cb8fe2787d..83183db896 100644
--- a/erts/emulator/beam/emu/emu_load.c
+++ b/erts/emulator/beam/emu/emu_load.c
@@ -327,6 +327,7 @@ int beam_load_finish_emit(LoaderState *stp) {
BeamCodeLineTab* const line_tab = (BeamCodeLineTab *) (codev+stp->ci);
const unsigned int ftab_size = stp->beam.code.function_count;
const unsigned int num_instrs = stp->current_li;
+ const unsigned int num_names = stp->beam.lines.name_count;
const void** const line_items =
(const void**) &line_tab->func_tab[ftab_size + 1];
const void *locp_base;
@@ -343,10 +344,10 @@ int beam_load_finish_emit(LoaderState *stp) {
}
line_items[i] = codev + stp->ci - 1;
- line_tab->fname_ptr = (Eterm*) &line_items[i + 1];
- if (stp->beam.lines.name_count) {
- sys_memcpy((void*)line_tab->fname_ptr, stp->beam.lines.names,
- stp->beam.lines.name_count*sizeof(Eterm));
+ line_tab->fname_ptr = (Eterm*)&line_items[i + 1];
+ for (i = 0; i < num_names; i++) {
+ Eterm *fname = (Eterm*)&line_tab->fname_ptr[i];
+ *fname = beamfile_get_literal(&stp->beam, stp->beam.lines.names[i]);
}
locp_base = &line_tab->fname_ptr[stp->beam.lines.name_count];
diff --git a/erts/emulator/beam/erl_binary.h b/erts/emulator/beam/erl_binary.h
index bd3a0632d2..d6b4e16417 100644
--- a/erts/emulator/beam/erl_binary.h
+++ b/erts/emulator/beam/erl_binary.h
@@ -271,7 +271,7 @@ void erts_init_binary(void);
byte* erts_get_aligned_binary_bytes_extra(Eterm, byte**, ErtsAlcType_t, unsigned extra);
/* Used by unicode module */
-Eterm erts_bin_bytes_to_list(Eterm previous, Eterm* hp, byte* bytes, Uint size, Uint bitoffs);
+Eterm erts_bin_bytes_to_list(Eterm previous, Eterm* hp, const byte* bytes, Uint size, Uint bitoffs);
/*
* Common implementation for erlang:list_to_binary/1 and binary:list_to_bin/1
diff --git a/erts/emulator/beam/erl_global_literals.h b/erts/emulator/beam/erl_global_literals.h
index 16974931b1..b926ce30ca 100644
--- a/erts/emulator/beam/erl_global_literals.h
+++ b/erts/emulator/beam/erl_global_literals.h
@@ -25,15 +25,12 @@
#define ERTS_LIT_OS_VERSION 1
#define ERTS_LIT_DFLAGS_RECORD 2
#define ERTS_LIT_EMPTY_TUPLE 3
+#define ERTS_LIT_ERL_FILE_SUFFIX 4
-#define ERTS_NUM_GLOBAL_LITERALS 4
-
-
+#define ERTS_NUM_GLOBAL_LITERALS 5
extern Eterm ERTS_GLOBAL_LIT_EMPTY_TUPLE;
-
-
Eterm* erts_alloc_global_literal(Uint index, Uint sz);
void erts_register_global_literal(Uint index, Eterm term);
Eterm erts_get_global_literal(Uint index);
diff --git a/erts/emulator/beam/erl_init.c b/erts/emulator/beam/erl_init.c
index c5e37a3822..d8866ea6af 100644
--- a/erts/emulator/beam/erl_init.c
+++ b/erts/emulator/beam/erl_init.c
@@ -393,6 +393,7 @@ erl_init(int ncpu,
packet_parser_init();
erl_nif_init();
erts_msacc_init();
+ beamfile_init();
}
static Eterm
diff --git a/erts/emulator/beam/erl_unicode.c b/erts/emulator/beam/erl_unicode.c
index 992ef9e3e4..45e07bf269 100644
--- a/erts/emulator/beam/erl_unicode.c
+++ b/erts/emulator/beam/erl_unicode.c
@@ -939,7 +939,7 @@ static int is_valid_utf8(Eterm orig_bin)
Uint bitsize;
Uint size;
byte *temp_alloc = NULL;
- byte *endpos;
+ const byte *endpos;
Uint numchar;
byte *bytes;
int ret;
@@ -1188,7 +1188,7 @@ BIF_RETTYPE unicode_characters_to_list_2(BIF_ALIST_2)
* a faster analyze and size count with this function.
*/
static ERTS_INLINE int
-analyze_utf8(byte *source, Uint size, byte **err_pos, Uint *num_chars, int *left,
+analyze_utf8(const byte *source, Uint size, const byte **err_pos, Uint *num_chars, int *left,
Sint *num_latin1_chars, Uint max_chars)
{
int res = ERTS_UTF8_OK;
@@ -1288,29 +1288,29 @@ analyze_utf8(byte *source, Uint size, byte **err_pos, Uint *num_chars, int *left
return res;
}
-int erts_analyze_utf8(byte *source, Uint size,
- byte **err_pos, Uint *num_chars, int *left)
+int erts_analyze_utf8(const byte *source, Uint size,
+ const byte **err_pos, Uint *num_chars, int *left)
{
return analyze_utf8(source, size, err_pos, num_chars, left, NULL, 0);
}
-int erts_analyze_utf8_x(byte *source, Uint size,
- byte **err_pos, Uint *num_chars, int *left,
+int erts_analyze_utf8_x(const byte *source, Uint size,
+ const byte **err_pos, Uint *num_chars, int *left,
Sint *num_latin1_chars, Uint max_chars)
{
return analyze_utf8(source, size, err_pos, num_chars, left, num_latin1_chars, max_chars);
}
-static ERTS_INLINE Eterm
-make_list_from_utf8_buf(Eterm **hpp, Uint num,
- byte *bytes, Uint sz,
- Uint *num_built, Uint *num_eaten,
- Eterm tail)
+Eterm
+erts_make_list_from_utf8_buf(Eterm **hpp, Uint num,
+ const byte *bytes, Uint sz,
+ Uint *num_built, Uint *num_eaten,
+ Eterm tail)
{
Eterm *hp;
Eterm ret;
Uint left = num;
- byte *source, *ssource;
+ const byte *source, *ssource;
Uint unipoint;
hp = *hpp;
ret = tail;
@@ -1369,9 +1369,9 @@ static Eterm do_utf8_to_list(Process *p, Uint num, byte *bytes, Uint sz,
hp = HAlloc(p,num * 2);
- return make_list_from_utf8_buf(&hp, num, bytes, sz,
- num_built, num_eaten,
- tail);
+ return erts_make_list_from_utf8_buf(&hp, num, bytes, sz,
+ num_built, num_eaten,
+ tail);
}
Eterm erts_utf8_to_list(Process *p, Uint num, byte *bytes, Uint sz, Uint left,
Uint *num_built, Uint *num_eaten, Eterm tail)
@@ -1389,7 +1389,7 @@ Uint erts_atom_to_string_length(Eterm atom)
if (ap->latin1_chars >= 0)
return (Uint) ap->len;
else {
- byte* err_pos;
+ const byte* err_pos;
Uint num_chars;
int ares =
erts_analyze_utf8(ap->name, ap->len, &err_pos, &num_chars, NULL);
@@ -1399,17 +1399,17 @@ Uint erts_atom_to_string_length(Eterm atom)
}
}
-Eterm erts_atom_to_string(Eterm **hpp, Eterm atom)
+Eterm erts_atom_to_string(Eterm **hpp, Eterm atom, Eterm tail)
{
Atom *ap;
ASSERT(is_atom(atom));
ap = atom_tab(atom_val(atom));
if (ap->latin1_chars >= 0)
- return buf_to_intlist(hpp, (char*)ap->name, ap->len, NIL);
+ return buf_to_intlist(hpp, (char*)ap->name, ap->len, tail);
else {
Eterm res;
- byte* err_pos;
+ const byte* err_pos;
Uint num_chars, num_built, num_eaten;
#ifdef DEBUG
Eterm *hp_start = *hpp;
@@ -1418,8 +1418,8 @@ Eterm erts_atom_to_string(Eterm **hpp, Eterm atom)
erts_analyze_utf8(ap->name, ap->len, &err_pos, &num_chars, NULL);
ASSERT(ares == ERTS_UTF8_OK);
- res = make_list_from_utf8_buf(hpp, num_chars, ap->name, ap->len,
- &num_built, &num_eaten, NIL);
+ res = erts_make_list_from_utf8_buf(hpp, num_chars, ap->name, ap->len,
+ &num_built, &num_eaten, tail);
ASSERT(num_built == num_chars);
ASSERT(num_eaten == ap->len);
@@ -1756,7 +1756,7 @@ static BIF_RETTYPE do_bif_utf8_to_list(Process *p,
Eterm *hp;
Eterm ret;
byte *temp_alloc = NULL;
- byte *endpos;
+ const byte *endpos;
Uint numchar;
Uint b_sz; /* size of the non analyzed tail */
@@ -2158,7 +2158,7 @@ char* erts_convert_filename_to_wchar(byte* bytes, Uint size,
ErtsAlcType_t alloc_type, Sint* used,
Uint extra_wchars)
{
- byte *err_pos;
+ const byte *err_pos;
Uint num_chars;
char* name_buf = NULL;
Sint need;
@@ -2200,7 +2200,7 @@ Eterm erts_convert_native_to_filename(Process *p, size_t size, byte *bytes)
{
Uint num_chars;
Eterm *hp;
- byte *err_pos;
+ const byte *err_pos;
Uint num_built; /* characters */
Uint num_eaten; /* bytes */
Eterm ret;
@@ -2678,7 +2678,7 @@ BIF_RETTYPE prim_file_internal_name2native_1(BIF_ALIST_1)
if (is_binary(BIF_ARG_1)) {
byte *temp_alloc = NULL;
byte *bytes;
- byte *err_pos;
+ const byte *err_pos;
Uint size,num_chars;
/* Uninterpreted encoding except if windows widechar, in case we convert from
utf8 to win_wchar */
@@ -2763,7 +2763,7 @@ BIF_RETTYPE prim_file_internal_native2name_1(BIF_ALIST_1)
Eterm *hp;
byte *temp_alloc = NULL;
byte *bytes;
- byte *err_pos;
+ const byte *err_pos;
Uint num_built; /* characters */
Uint num_eaten; /* bytes */
Eterm ret;
@@ -2857,7 +2857,7 @@ BIF_RETTYPE prim_file_internal_normalize_utf8_1(BIF_ALIST_1)
Eterm ret;
byte *temp_alloc = NULL;
byte *bytes;
- byte *err_pos;
+ const byte *err_pos;
if (is_not_binary(BIF_ARG_1)) {
BIF_ERROR(BIF_P,BADARG);
@@ -2890,7 +2890,7 @@ BIF_RETTYPE prim_file_is_translatable_1(BIF_ALIST_1)
ERTS_DECLARE_DUMMY(Uint bitoffs);
byte *temp_alloc = NULL;
byte *bytes;
- byte *err_pos;
+ const byte *err_pos;
int status;
if (is_not_binary(BIF_ARG_1)) {
diff --git a/erts/emulator/beam/erl_unicode.h b/erts/emulator/beam/erl_unicode.h
index 31369fc8f9..22d90bcd71 100644
--- a/erts/emulator/beam/erl_unicode.h
+++ b/erts/emulator/beam/erl_unicode.h
@@ -22,6 +22,6 @@
#define _ERL_UNICODE_H
Uint erts_atom_to_string_length(Eterm atom);
-Eterm erts_atom_to_string(Eterm **hpp, Eterm atom);
+Eterm erts_atom_to_string(Eterm **hpp, Eterm atom, Eterm tail);
#endif /* _ERL_UNICODE_H */
diff --git a/erts/emulator/beam/global.h b/erts/emulator/beam/global.h
index efd34ce6bf..f1f44351b3 100644
--- a/erts/emulator/beam/global.h
+++ b/erts/emulator/beam/global.h
@@ -1492,10 +1492,10 @@ Sint erts_unicode_set_loop_limit(Sint limit);
void erts_native_filename_put(Eterm ioterm, int encoding, byte *p) ;
Sint erts_native_filename_need(Eterm ioterm, int encoding);
void erts_copy_utf8_to_utf16_little(byte *target, byte *bytes, int num_chars);
-int erts_analyze_utf8(byte *source, Uint size,
- byte **err_pos, Uint *num_chars, int *left);
-int erts_analyze_utf8_x(byte *source, Uint size,
- byte **err_pos, Uint *num_chars, int *left,
+int erts_analyze_utf8(const byte *source, Uint size,
+ const byte **err_pos, Uint *num_chars, int *left);
+int erts_analyze_utf8_x(const byte *source, Uint size,
+ const byte **err_pos, Uint *num_chars, int *left,
Sint *num_latin1_chars, Uint max_chars);
char *erts_convert_filename_to_native(Eterm name, char *statbuf,
size_t statbuf_size,
@@ -1516,6 +1516,11 @@ char* erts_convert_filename_to_wchar(byte* bytes, Uint size,
Eterm erts_convert_native_to_filename(Process *p, size_t size, byte *bytes);
Eterm erts_utf8_to_list(Process *p, Uint num, byte *bytes, Uint sz, Uint left,
Uint *num_built, Uint *num_eaten, Eterm tail);
+Eterm
+erts_make_list_from_utf8_buf(Eterm **hpp, Uint num,
+ const byte *bytes, Uint sz,
+ Uint *num_built, Uint *num_eaten,
+ Eterm tail);
int erts_utf8_to_latin1(byte* dest, const byte* source, int slen);
#define ERTS_UTF8_OK 0
#define ERTS_UTF8_INCOMPLETE 1
diff --git a/erts/emulator/beam/jit/asm_load.c b/erts/emulator/beam/jit/asm_load.c
index dd0f049fe1..f316ef1ed5 100644
--- a/erts/emulator/beam/jit/asm_load.c
+++ b/erts/emulator/beam/jit/asm_load.c
@@ -641,6 +641,7 @@ static const BeamCodeLineTab *finish_line_table(LoaderState *stp,
const void **line_items_ro;
void **line_items_rw;
+ const unsigned int num_names = stp->beam.lines.name_count;
const Eterm *fname_base_ro;
Eterm *fname_base_rw;
@@ -685,10 +686,9 @@ static const BeamCodeLineTab *finish_line_table(LoaderState *stp,
line_items_rw[i] = (void *)&module_base[module_size];
- if (stp->beam.lines.name_count) {
- sys_memcpy(fname_base_rw,
- stp->beam.lines.names,
- stp->beam.lines.name_count * sizeof(Eterm));
+ for (i = 0; i < num_names; i++) {
+ fname_base_rw[i] = beamfile_get_literal(&stp->beam,
+ stp->beam.lines.names[i]);
}
if (stp->beam.lines.location_size == sizeof(Uint16)) {
@@ -787,15 +787,6 @@ int beam_load_finish_emit(LoaderState *stp) {
stp->on_load = beamasm_get_on_load(stp->ba);
- /* If there is line information, place it here. This must be done after
- * code generation to make sure the addresses are correct.
- *
- * Ideally we'd want this to be embedded in the module itself just like the
- * string table is and use offsets rather than absolute addresses, but this
- * will do for now. */
-
- code_hdr_rw->line_table = finish_line_table(stp, module_base, module_size);
-
/*
* Place the literals in their own allocated heap (for fast range check)
* and fix up all instructions that refer to it.
@@ -839,6 +830,10 @@ int beam_load_finish_emit(LoaderState *stp) {
(stp->load_hdr)->literal_area = literal_area;
}
+ /* Line information must be added after moving literals, since source file
+ * names are literal lists. */
+ code_hdr_rw->line_table = finish_line_table(stp, module_base, module_size);
+
if (stp->beam.attributes.size) {
const byte *attr = beamasm_get_rodata(stp->ba, "attr");
diff --git a/erts/emulator/beam/utils.c b/erts/emulator/beam/utils.c
index 61d5924c9e..87c91c035c 100644
--- a/erts/emulator/beam/utils.c
+++ b/erts/emulator/beam/utils.c
@@ -5190,15 +5190,7 @@ erts_build_mfa_item(FunctionInfo* fi, Eterm* hp, Eterm args, Eterm* mfa_p, Eterm
Eterm tuple;
int line = LOC_LINE(fi->loc);
int file = LOC_FILE(fi->loc);
- Eterm file_term = NIL;
-
- if (file == 0) {
- Atom* ap = atom_tab(atom_val(fi->mfa->module));
- file_term = buf_to_intlist(&hp, ".erl", 4, NIL);
- file_term = buf_to_intlist(&hp, (char*)ap->name, ap->len, file_term);
- } else {
- file_term = erts_atom_to_string(&hp, (fi->fname_ptr)[file-1]);
- }
+ Eterm file_term = fi->fname_ptr[file];
tuple = TUPLE2(hp, am_line, make_small(line));
hp += 3;
diff --git a/erts/etc/unix/etp-commands.in b/erts/etc/unix/etp-commands.in
index 19bd40fe02..fbfb3e5022 100644
--- a/erts/etc/unix/etp-commands.in
+++ b/erts/etc/unix/etp-commands.in
@@ -1284,11 +1284,7 @@ define etp-cp-line-info
if $etp_loc != 0
set $etp_loc_file = $etp_loc >> 24
set $etp_cp_line_number = $etp_loc & ((1 << 24) - 1)
- if $etp_loc_file == 0
- set $etp_cp_line_name = $etp_line_mfa->module
- else
- set $etp_cp_line_name = $etp_line_table->fname_ptr[$etp_loc_file - 1]
- end
+ set $etp_cp_line_name = $etp_line_table->fname_ptr[$etp_loc_file]
end
end
end
@@ -1364,7 +1360,7 @@ define etp-cp-1
etp-mfa-1 $etp_cp_p $cp_cp_p_offset
if $etp_cp_line_name != $etp_nil
printf " @ "
- etp-atom-1 $etp_cp_line_name
+ etp-1 $etp_cp_line_name 0
printf ":%u", $etp_cp_line_number
end
else